Beispiel #1
0
        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
        }
Beispiel #2
0
        public static int GenerateOutput(ref DSConfig config)
        {
            // Write Output
            Helper.WriteOutput(ref config);

            return(Constants.DONUT_ERROR_SUCCESS);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        // 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 { };
        }
Beispiel #5
0
        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++;
        }
Beispiel #6
0
        // 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);
        }
Beispiel #7
0
        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++;
            }
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
 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");
 }
Beispiel #10
0
        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;
        }
Beispiel #11
0
        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);
            }
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
            }
        }
Beispiel #16
0
        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");
            }
        }
Beispiel #17
0
 public static byte[] GenerateOutput(ref DSConfig config)
 {
     return(Helper.GetOutput(ref config));
 }
Beispiel #18
0
        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);
        }
Beispiel #19
0
        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);
        }
Beispiel #20
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 { };
        }
Beispiel #21
0
        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);
        }
Beispiel #22
0
        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);
        }
Beispiel #23
0
        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);
        }
Beispiel #24
0
        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);
        }
Beispiel #25
0
        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);
        }