예제 #1
0
        // the host enumeration block we're using to enumerate all servers

        private static IEnumerable <string> _Find_LocalAdminAccess(string[] ComputerName, IntPtr TokenHandle)

        {
            var LogonToken = IntPtr.Zero;

            if (TokenHandle != IntPtr.Zero)

            {
                // impersonate the the token produced by LogonUser()/Invoke-UserImpersonation

                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation

                {
                    TokenHandle = TokenHandle,

                    Quiet = true
                });
            }



            var TargetComputers = new List <string>();

            foreach (var TargetComputer in ComputerName)

            {
                var Up = TestConnection.Ping(TargetComputer, 1);

                if (Up)
                {
                    // check if the current user has local admin access to this server

                    var Access = TestAdminAccess.Test_AdminAccess(new Args_Test_AdminAccess {
                        ComputerName = new[] { TargetComputer }
                    }).FirstOrDefault();

                    if (Access != null && Access.IsAdmin)
                    {
                        TargetComputers.Add(TargetComputer);
                    }
                }
            }



            if (TokenHandle != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }

            return(TargetComputers);
        }
예제 #2
0
        public static IEnumerable <AdminAccess> Test_AdminAccess(Args_Test_AdminAccess args = null)
        {
            if (args == null)
            {
                args = new Args_Test_AdminAccess();
            }

            IntPtr LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation {
                    Credential = args.Credential
                });
            }

            var IsAdmins = new List <AdminAccess>();

            foreach (var Computer in args.ComputerName)
            {
                // 0xF003F - SC_MANAGER_ALL_ACCESS
                // http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
                var Handle    = NativeMethods.OpenSCManagerW($@"\\{Computer}", "ServicesActive", 0xF003F);
                var LastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();

                var IsAdmin = new AdminAccess
                {
                    ComputerName = Computer
                };

                // if we get a non-zero handle back, everything was successful
                if (Handle != IntPtr.Zero)
                {
                    NativeMethods.CloseServiceHandle(Handle);
                    IsAdmin.IsAdmin = true;
                }
                else
                {
                    Logger.Write_Verbose($@"[Test-AdminAccess] Error: {new System.ComponentModel.Win32Exception((int)LastError).Message}");
                    IsAdmin.IsAdmin = false;
                }
                IsAdmins.Add(IsAdmin);
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }

            return(IsAdmins);
        }
예제 #3
0
        // the host enumeration block we're using to enumerate all servers
        private static IEnumerable <object> _Find_DomainLocalGroupMember(string[] ComputerName, string GroupName, MethodType Method, IntPtr TokenHandle)
        {
            // Add check if user defaults to/selects "Administrators"
            if (GroupName == "Administrators")
            {
                var AdminSecurityIdentifier = new System.Security.Principal.SecurityIdentifier(System.Security.Principal.WellKnownSidType.BuiltinAdministratorsSid, null);
                GroupName = AdminSecurityIdentifier.Translate(typeof(System.Security.Principal.NTAccount)).Value.Split('\\').LastOrDefault();
            }

            var LogonToken = IntPtr.Zero;

            if (TokenHandle != IntPtr.Zero)
            {
                // impersonate the the token produced by LogonUser()/Invoke-UserImpersonation
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    TokenHandle = TokenHandle,
                    Quiet       = true
                });
            }

            var Members = new List <object>();

            foreach (var TargetComputer in ComputerName)
            {
                var Up = TestConnection.Ping(TargetComputer, 1);
                if (Up)
                {
                    var NetLocalGroupMemberArguments = new Args_Get_NetLocalGroupMember
                    {
                        ComputerName = new[] { TargetComputer },
                        Method       = Method,
                        GroupName    = GroupName
                    };
                    var ret = GetNetLocalGroupMember.Get_NetLocalGroupMember(NetLocalGroupMemberArguments);
                    if (ret != null)
                    {
                        Members.AddRange(ret);
                    }
                }
            }

            if (TokenHandle != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(Members);
        }
예제 #4
0
        public static IEnumerable <RDPSessionInfo> Get_NetRDPSession(Args_Get_NetRDPSession args = null)
        {
            if (args == null)
            {
                args = new Args_Get_NetRDPSession();
            }

            IntPtr LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation {
                    Credential = args.Credential
                });
            }

            var RDPSessions = new List <RDPSessionInfo>();

            foreach (var Computer in args.ComputerName)
            {
                // open up a handle to the Remote Desktop Session host
                var Handle = NativeMethods.WTSOpenServerEx(Computer);

                // if we get a non-zero handle back, everything was successful
                if (Handle != IntPtr.Zero)
                {
                    // arguments for WTSEnumerateSessionsEx
                    var    ppSessionInfo = IntPtr.Zero;
                    UInt32 pCount        = 0;

                    // get information on all current sessions
                    UInt32 level     = 1;
                    var    Result    = NativeMethods.WTSEnumerateSessionsEx(Handle, ref level, 0, ref ppSessionInfo, ref pCount);
                    var    LastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();

                    // locate the offset of the initial intPtr
                    var Offset = ppSessionInfo.ToInt64();

                    if ((Result != 0) && (Offset > 0))
                    {
                        // work out how much to increment the pointer by finding out the size of the structure
                        var Increment = Marshal.SizeOf(typeof(NativeMethods.WTS_SESSION_INFO_1));

                        // parse all the result structures
                        for (var i = 0; (i < pCount); i++)
                        {
                            // create a new int ptr at the given offset and cast the pointer as our result structure
                            var NewIntPtr = new IntPtr(Offset);
                            var Info      = (NativeMethods.WTS_SESSION_INFO_1)Marshal.PtrToStructure(NewIntPtr, typeof(NativeMethods.WTS_SESSION_INFO_1));

                            var RDPSession = new RDPSessionInfo();

                            if (Info.pHostName != null)
                            {
                                RDPSession.ComputerName = Info.pHostName;
                            }
                            else
                            {
                                // if no hostname returned, use the specified hostname
                                RDPSession.ComputerName = Computer;
                            }

                            RDPSession.SessionName = Info.pSessionName;

                            if ((Info.pDomainName == null) || (Info.pDomainName == ""))
                            {
                                // if a domain isn't returned just use the username
                                RDPSession.UserName = Info.pUserName;
                            }
                            else
                            {
                                RDPSession.UserName = $@"{Info.pDomainName}\{Info.pUserName}";
                            }

                            RDPSession.ID    = Info.SessionId;
                            RDPSession.State = Info.State;

                            var  ppBuffer       = IntPtr.Zero;
                            uint pBytesReturned = 0;

                            // query for the source client IP with WTSQuerySessionInformation
                            // https://msdn.microsoft.com/en-us/library/aa383861(v=vs.85).aspx
                            var Result2    = NativeMethods.WTSQuerySessionInformation(Handle, Info.SessionId, NativeMethods.WTS_INFO_CLASS.WTSClientAddress, out ppBuffer, out pBytesReturned);
                            var LastError2 = System.Runtime.InteropServices.Marshal.GetLastWin32Error();

                            if (Result2 == false)
                            {
                                Logger.Write_Verbose($@"[Get-NetRDPSession] Error: {new System.ComponentModel.Win32Exception((int)LastError2).Message}");
                            }
                            else
                            {
                                var Offset2    = ppBuffer.ToInt64();
                                var NewIntPtr2 = new IntPtr(Offset2);
                                var Info2      = (NativeMethods.WTS_CLIENT_ADDRESS)Marshal.PtrToStructure(NewIntPtr2, typeof(NativeMethods.WTS_CLIENT_ADDRESS));

                                string SourceIP;
                                if (Info2.Address[2] != 0)
                                {
                                    SourceIP = $@"{Info2.Address[2]}.{Info2.Address[3]}.{Info2.Address[4]}.{Info2.Address[5]}";
                                }
                                else
                                {
                                    SourceIP = null;
                                }

                                RDPSession.SourceIP = SourceIP;
                                RDPSessions.Add(RDPSession);

                                // free up the memory buffer
                                NativeMethods.WTSFreeMemory(ppBuffer);

                                Offset += Increment;
                            }
                        }
                        // free up the memory result buffer
                        NativeMethods.WTSFreeMemoryEx(WTS_TYPE_CLASS.WTSTypeSessionInfoLevel1, ppSessionInfo, pCount);
                    }
                    else
                    {
                        Logger.Write_Verbose($@"[Get-NetRDPSession] Error: {new System.ComponentModel.Win32Exception((int)LastError).Message}");
                    }
                    // close off the service handle
                    NativeMethods.WTSCloseServer(Handle);
                }
                else
                {
                    Logger.Write_Verbose($@"[Get-NetRDPSession] Error opening the Remote Desktop Session Host (RD Session Host) server for: {Computer}");
                }
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }

            return(RDPSessions);
        }
예제 #5
0
        // the host enumeration block we're using to enumerate all servers
        private static IEnumerable <FoundFile> _Find_InterestingDomainShareFile(string[] ComputerName, string[] Include, string[] ExcludedShares, bool OfficeDocs, bool ExcludeHidden, bool FreshEXEs, bool CheckWriteAccess, DateTime?LastAccessTime, DateTime?LastWriteTime, DateTime?CreationTime, IntPtr TokenHandle)
        {
            var LogonToken = IntPtr.Zero;

            if (TokenHandle != IntPtr.Zero)
            {
                // impersonate the the token produced by LogonUser()/Invoke-UserImpersonation
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    TokenHandle = TokenHandle,
                    Quiet       = true
                });
            }

            var FoundFiles = new List <FoundFile>();

            foreach (var TargetComputer in ComputerName)
            {
                var SearchShares = new List <string>();
                if (TargetComputer.StartsWith(@"\\"))
                {
                    // if a share is passed as the server
                    SearchShares.Add(TargetComputer);
                }
                else
                {
                    var Up = TestConnection.Ping(TargetComputer, 1);
                    if (Up)
                    {
                        // get the shares for this host and check what we find
                        var Shares = GetNetShare.Get_NetShare(new Args_Get_NetShare
                        {
                            ComputerName = new[] { TargetComputer }
                        });

                        foreach (var Share in Shares)
                        {
                            var ShareName = Share.Name;
                            var Path      = @"\\" + TargetComputer + @"\" + ShareName;

                            // make sure we get a real share name back
                            if ((!string.IsNullOrEmpty(ShareName)) && (ShareName.Trim() != ""))
                            {
                                // skip this share if it's in the exclude list
                                if (!ExcludedShares.ContainsNoCase(ShareName))
                                {
                                    // check if the user has access to this path
                                    try
                                    {
                                        Directory.GetFiles(Path);
                                        SearchShares.Add(Path);
                                    }
                                    catch
                                    {
                                        Logger.Write_Verbose($@"[!] No access to {Path}");
                                    }
                                }
                            }
                        }
                    }
                }

                foreach (var Share in SearchShares)
                {
                    Logger.Write_Verbose($@"Searching share: {Share}");
                    var SearchArgs = new Args_Find_InterestingFile
                    {
                        Path    = new[] { Share },
                        Include = Include
                    };
                    if (OfficeDocs)
                    {
                        SearchArgs.OfficeDocs = OfficeDocs;
                    }
                    if (FreshEXEs)
                    {
                        SearchArgs.FreshEXEs = FreshEXEs;
                    }
                    if (LastAccessTime != null)
                    {
                        SearchArgs.LastAccessTime = LastAccessTime;
                    }
                    if (LastWriteTime != null)
                    {
                        SearchArgs.LastWriteTime = LastWriteTime;
                    }
                    if (CreationTime != null)
                    {
                        SearchArgs.CreationTime = CreationTime;
                    }
                    if (CheckWriteAccess)
                    {
                        SearchArgs.CheckWriteAccess = CheckWriteAccess;
                    }
                    FoundFiles.AddRange(Find_InterestingFile(SearchArgs));
                }
            }

            if (TokenHandle != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(FoundFiles);
        }
        public static IEnumerable <FoundFile> Find_InterestingDomainShareFile(Args_Find_InterestingDomainShareFile args = null)
        {
            if (args == null)
            {
                args = new Args_Find_InterestingDomainShareFile();
            }

            var ComputerSearcherArguments = new Args_Get_DomainComputer
            {
                Properties      = new[] { "dnshostname" },
                Domain          = args.ComputerDomain,
                LDAPFilter      = args.ComputerLDAPFilter,
                SearchBase      = args.ComputerSearchBase,
                OperatingSystem = args.OperatingSystem,
                ServicePack     = args.ServicePack,
                SiteName        = args.SiteName,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            string[] TargetComputers;
            if (args.ComputerName != null)
            {
                TargetComputers = args.ComputerName;
            }
            else
            {
                Logger.Write_Verbose($@"[Find-InterestingDomainShareFile] Querying computers in the domain");
                TargetComputers = GetDomainComputer.Get_DomainComputer(ComputerSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
            }

            if (TargetComputers == null || TargetComputers.Length == 0)
            {
                throw new Exception("[Find-InterestingDomainShareFile] No hosts found to enumerate");
            }
            Logger.Write_Verbose($@"[Find-InterestingDomainShareFile] TargetComputers length: {TargetComputers.Length}");

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                if (args.Delay != 0 || args.StopOnSuccess)
                {
                    LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                    {
                        Credential = args.Credential
                    });
                }
                else
                {
                    LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                    {
                        Credential = args.Credential,
                        Quiet      = true
                    });
                }
            }

            var rets = new List <FoundFile>();

            // only ignore threading if -Delay is passed
            if (args.Delay != 0 || args.StopOnSuccess)
            {
                Logger.Write_Verbose($@"[Find-InterestingDomainShareFile] Total number of hosts: {TargetComputers.Count()}");
                Logger.Write_Verbose($@"[Find-InterestingDomainShareFile] Delay: {args.Delay}, Jitter: {args.Jitter}");

                var Counter = 0;
                var RandNo  = new System.Random();

                foreach (var TargetComputer in TargetComputers)
                {
                    Counter = Counter + 1;

                    // sleep for our semi-randomized interval
                    System.Threading.Thread.Sleep(RandNo.Next((int)((1 - args.Jitter) * args.Delay), (int)((1 + args.Jitter) * args.Delay)) * 1000);

                    Logger.Write_Verbose($@"[Find-InterestingDomainShareFile] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})");
                    var ret = _Find_InterestingDomainShareFile(new[] { TargetComputer }, args.Include, args.ExcludedShares, args.OfficeDocs, /*args.ExcludeHidden*/ false, args.FreshEXEs, /*args.CheckWriteAccess*/ false, args.LastAccessTime, args.LastWriteTime, args.CreationTime, LogonToken);
                    if (ret != null)
                    {
                        rets.AddRange(ret);
                    }
                }
            }
            else
            {
                Logger.Write_Verbose($@"[Find-InterestingDomainShareFile] Using threading with threads: {args.Threads}");

                // if we're using threading, kick off the script block with New-ThreadedFunction
                // if we're using threading, kick off the script block with New-ThreadedFunction using the $HostEnumBlock + params
                System.Threading.Tasks.Parallel.ForEach(
                    TargetComputers,
                    TargetComputer =>
                {
                    var ret = _Find_InterestingDomainShareFile(new[] { TargetComputer }, args.Include, args.ExcludedShares, args.OfficeDocs, /*args.ExcludeHidden*/ false, args.FreshEXEs, /*args.CheckWriteAccess*/ false, args.LastAccessTime, args.LastWriteTime, args.CreationTime, LogonToken);
                    lock (rets)
                    {
                        if (ret != null)
                        {
                            rets.AddRange(ret);
                        }
                    }
                });
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(rets);
        }
예제 #7
0
        public static IEnumerable <object> Get_NetLocalGroupMember(Args_Get_NetLocalGroupMember args = null)
        {
            if (args == null)
            {
                args = new Args_Get_NetLocalGroupMember();
            }

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    Credential = args.Credential
                });
            }

            var LocalGroupMembers = new List <object>();

            foreach (var Computer in args.ComputerName)
            {
                if (args.Method == MethodType.API)
                {
                    // if we're using the Netapi32 NetLocalGroupGetMembers API call to get the local group information
                    // arguments for NetLocalGroupGetMembers
                    var QueryLevel   = 2;
                    var PtrInfo      = IntPtr.Zero;
                    var EntriesRead  = 0;
                    var TotalRead    = 0;
                    var ResumeHandle = IntPtr.Zero;

                    // get the local user information
                    var Result = NativeMethods.NetLocalGroupGetMembers(Computer, args.GroupName, QueryLevel, out PtrInfo, -1, out EntriesRead, out TotalRead, ResumeHandle);

                    // locate the offset of the initial intPtr
                    var Offset = PtrInfo.ToInt64();

                    var Members = new List <object>();

                    // 0 = success
                    if ((Result == 0) && (Offset > 0))
                    {
                        // Work out how much to increment the pointer by finding out the size of the structure
                        var Increment = Marshal.SizeOf(typeof(LOCALGROUP_MEMBERS_INFO_2));

                        // parse all the result structures
                        for (var i = 0; (i < EntriesRead); i++)
                        {
                            // create a new int ptr at the given offset and cast the pointer as our result structure
                            var NewIntPtr = new System.IntPtr(Offset);
                            var Info      = (LOCALGROUP_MEMBERS_INFO_2)Marshal.PtrToStructure(NewIntPtr, typeof(LOCALGROUP_MEMBERS_INFO_2));

                            Offset  = NewIntPtr.ToInt64();
                            Offset += Increment;

                            var SidString = "";
                            var Result2   = NativeMethods.ConvertSidToStringSid(Info.lgrmi2_sid, out SidString);
                            var LastError = System.Runtime.InteropServices.Marshal.GetLastWin32Error();

                            if (!Result2)
                            {
                                Logger.Write_Verbose($@"[Get-NetLocalGroupMember] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");
                            }
                            else
                            {
                                var Member = new LocalGroupMemberAPI
                                {
                                    ComputerName = Computer,
                                    GroupName    = args.GroupName,
                                    MemberName   = Info.lgrmi2_domainandname,
                                    SID          = SidString,
                                    IsGroup      = Info.lgrmi2_sidusage == SID_NAME_USE.SidTypeGroup
                                };
                                Members.Add(Member);
                            }
                        }

                        // free up the result buffer
                        NativeMethods.NetApiBufferFree(PtrInfo);

                        // try to extract out the machine SID by using the -500 account as a reference
                        var MachineSid = (Members.FirstOrDefault(x => (x as LocalGroupMemberAPI).SID.IsRegexMatch(".*-500") || (x as LocalGroupMemberAPI).SID.IsRegexMatch(".*-501")) as LocalGroupMemberAPI).SID;
                        if (MachineSid != null)
                        {
                            MachineSid = MachineSid.Substring(0, MachineSid.LastIndexOf('-'));

                            foreach (LocalGroupMemberAPI member in Members)
                            {
                                if (member.SID.IsRegexMatch(MachineSid))
                                {
                                    member.IsDomain = "false";
                                }
                                else
                                {
                                    member.IsDomain = "true";
                                }
                            }
                        }
                        else
                        {
                            foreach (LocalGroupMemberAPI member in Members)
                            {
                                if (!member.SID.IsRegexMatch("S-1-5-21"))
                                {
                                    member.IsDomain = "false";
                                }
                                else
                                {
                                    member.IsDomain = "UNKNOWN";
                                }
                            }
                        }
                        LocalGroupMembers.AddRange(Members);
                    }
                    else
                    {
                        Logger.Write_Verbose($@"[Get-NetLocalGroupMember] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");
                    }
                }
                else
                {
                    // otherwise we're using the WinNT service provider
                    try
                    {
                        var         GroupProvider = new System.DirectoryServices.DirectoryEntry($@"WinNT://{Computer}/{args.GroupName},group");
                        IEnumerable Members       = (IEnumerable)GroupProvider.Invoke("Members");
                        foreach (var obj in Members)
                        {
                            var LocalUser = new System.DirectoryServices.DirectoryEntry(obj);
                            var Member    = new LocalGroupMemberWinNT
                            {
                                ComputerName = Computer,
                                GroupName    = args.GroupName
                            };

                            var AdsPath = LocalUser.InvokeGet("AdsPath").ToString().Replace("WinNT://", "");
                            var IsGroup = LocalUser.SchemaClassName.IsLikeMatch("group");

                            bool   MemberIsDomain;
                            string Name;
                            if (Regex.Matches(AdsPath, "/").Count == 1)
                            {
                                // DOMAIN\user
                                MemberIsDomain = true;
                                Name           = AdsPath.Replace(@"/", @"\");
                            }
                            else
                            {
                                // DOMAIN\machine\user
                                MemberIsDomain = false;
                                Name           = AdsPath.Substring(AdsPath.IndexOf('/') + 1).Replace(@"/", @"\");
                            }

                            Member.AccountName = Name;
                            Member.SID         = new System.Security.Principal.SecurityIdentifier((byte[])LocalUser.InvokeGet("ObjectSID"), 0).Value;
                            Member.IsGroup     = IsGroup;
                            Member.IsDomain    = MemberIsDomain;

                            LocalGroupMembers.Add(Member);
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Write_Verbose($@"[Get-NetLocalGroupMember] Error for {Computer} : {e}");
                    }
                }
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(LocalGroupMembers);
        }
예제 #8
0
        public static IEnumerable <ShareInfo> Get_NetShare(Args_Get_NetShare args = null)
        {
            if (args == null)
            {
                args = new Args_Get_NetShare();
            }

            var shareInfos = new List <ShareInfo>();

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    Credential = args.Credential
                });
            }
            foreach (var Computer in args.ComputerName)
            {
                // arguments for NetShareEnum
                var QueryLevel   = 1;
                var PtrInfo      = IntPtr.Zero;
                var EntriesRead  = 0;
                var TotalRead    = 0;
                var ResumeHandle = 0;

                // get the raw share information
                var Result = NativeMethods.NetShareEnum(Computer, QueryLevel, ref PtrInfo, MAX_PREFERRED_LENGTH, ref EntriesRead, ref TotalRead, ref ResumeHandle);

                // locate the offset of the initial intPtr
                var Offset = PtrInfo.ToInt64();

                // 0 = success
                if ((Result == 0) && (Offset > 0))
                {
                    // work out how much to increment the pointer by finding out the size of the structure
                    var Increment = Marshal.SizeOf(typeof(SHARE_INFO_1));

                    // parse all the result structures
                    for (var i = 0; (i < EntriesRead); i++)
                    {
                        // create a new int ptr at the given offset and cast the pointer as our result structure
                        var NewIntPtr = new System.IntPtr(Offset);
                        var Info      = (SHARE_INFO_1)Marshal.PtrToStructure(NewIntPtr, typeof(SHARE_INFO_1));

                        // return all the sections of the structure - have to do it this way for V2
                        shareInfos.Add(new ShareInfo
                        {
                            Name         = Info.shi1_netname,
                            Type         = Info.shi1_type,
                            Remark       = Info.shi1_remark,
                            ComputerName = Computer
                        });
                        Offset  = NewIntPtr.ToInt64();
                        Offset += Increment;
                    }

                    // free up the result buffer
                    NativeMethods.NetApiBufferFree(PtrInfo);
                }
                else
                {
                    Logger.Write_Verbose($@"[Get-NetShare] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");
                }
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(shareInfos);
        }
예제 #9
0
        public static IEnumerable <object> Get_NetLocalGroup(Args_Get_NetLocalGroup args = null)
        {
            if (args == null)
            {
                args = new Args_Get_NetLocalGroup();
            }

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    Credential = args.Credential
                });
            }

            var LocalGroups = new List <object>();

            foreach (var Computer in args.ComputerName)
            {
                if (args.Method == MethodType.API)
                {
                    // if we're using the Netapi32 NetLocalGroupEnum API call to get the local group information
                    // arguments for NetLocalGroupEnum
                    var QueryLevel   = 1;
                    var PtrInfo      = IntPtr.Zero;
                    var EntriesRead  = 0;
                    var TotalRead    = 0;
                    var ResumeHandle = 0;

                    // get the local user information
                    var Result = NativeMethods.NetLocalGroupEnum(Computer, QueryLevel, out PtrInfo, MAX_PREFERRED_LENGTH, out EntriesRead, out TotalRead, ref ResumeHandle);

                    // locate the offset of the initial intPtr
                    var Offset = PtrInfo.ToInt64();

                    // 0 = success
                    if ((Result == 0) && (Offset > 0))
                    {
                        // Work out how much to increment the pointer by finding out the size of the structure
                        var Increment = Marshal.SizeOf(typeof(LOCALGROUP_INFO_1));

                        // parse all the result structures
                        for (var i = 0; (i < EntriesRead); i++)
                        {
                            // create a new int ptr at the given offset and cast the pointer as our result structure
                            var NewIntPtr = new System.IntPtr(Offset);
                            var Info      = (LOCALGROUP_INFO_1)Marshal.PtrToStructure(NewIntPtr, typeof(LOCALGROUP_INFO_1));

                            LocalGroups.Add(new LocalGroupAPI
                            {
                                ComputerName = Computer,
                                GroupName    = Info.lgrpi1_name,
                                Comment      = Info.lgrpi1_comment
                            });
                            Offset  = NewIntPtr.ToInt64();
                            Offset += Increment;
                        }
                        // free up the result buffer
                        NativeMethods.NetApiBufferFree(PtrInfo);
                    }
                    else
                    {
                        Logger.Write_Verbose($@"[Get-NetLocalGroup] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");
                    }
                }
                else
                {
                    // otherwise we're using the WinNT service provider
                    var ComputerProvider = new System.DirectoryServices.DirectoryEntry($@"WinNT://{Computer},computer");
                    foreach (System.DirectoryServices.DirectoryEntry LocalGroup in ComputerProvider.Children)
                    {
                        if (LocalGroup.SchemaClassName.Equals("group", StringComparison.OrdinalIgnoreCase))
                        {
                            var Group = new LocalGroupWinNT
                            {
                                ComputerName = Computer,
                                GroupName    = LocalGroup.Name,
                                SID          = new System.Security.Principal.SecurityIdentifier((byte[])LocalGroup.InvokeGet("objectsid"), 0).Value,
                                Comment      = LocalGroup.InvokeGet("Description").ToString()
                            };
                            LocalGroups.Add(Group);
                        }
                    }
                }
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(LocalGroups);
        }
예제 #10
0
        public static IEnumerable <RegLoggedOnUser> Get_RegLoggedOn(Args_Get_RegLoggedOn args = null)
        {
            if (args == null)
            {
                args = new Args_Get_RegLoggedOn();
            }

            IntPtr LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation {
                    Credential = args.Credential
                });
            }

            var RegLoggedOnUsers = new List <RegLoggedOnUser>();

            foreach (var Computer in args.ComputerName)
            {
                try
                {
                    // retrieve HKU remote registry values
                    var Reg = Microsoft.Win32.RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.Users, $@"{Computer}");

                    // sort out bogus sid's like _class
                    var subkeys = Reg.GetSubKeyNames()?.Where(x => x.IsRegexMatch(@"S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]+$"));

                    foreach (var subkey in subkeys)
                    {
                        var UserName = ConvertFromSID.ConvertFrom_SID(new Args_ConvertFrom_SID {
                            ObjectSID = new[] { subkey }
                        }).FirstOrDefault();
                        string UserDomain;

                        if (UserName != null)
                        {
                            UserName   = UserName.Split('@')[0];
                            UserDomain = UserName.Split('@')[1];
                        }
                        else
                        {
                            UserName   = subkey;
                            UserDomain = null;
                        }

                        var RegLoggedOnUser = new RegLoggedOnUser
                        {
                            ComputerName = $@"{Computer}",
                            UserDomain   = UserDomain,
                            UserName     = UserName,
                            UserSID      = subkey
                        };
                        RegLoggedOnUsers.Add(RegLoggedOnUser);
                    }
                }
                catch (Exception e)
                {
                    Logger.Write_Verbose($@"[Get-RegLoggedOn] Error opening remote registry on '{Computer}' : {e}");
                }
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }

            return(RegLoggedOnUsers);
        }
예제 #11
0
        public static IEnumerable <SessionInfo> Get_NetSession(Args_Get_NetSession args = null)
        {
            if (args == null)
            {
                args = new Args_Get_NetSession();
            }

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    Credential = args.Credential
                });
            }

            var SessionInfos = new List <SessionInfo>();

            foreach (var Computer in args.ComputerName)
            {
                // arguments for NetSessionEnum
                var QueryLevel   = 10;
                var PtrInfo      = IntPtr.Zero;
                var EntriesRead  = 0;
                var TotalRead    = 0;
                var ResumeHandle = 0;
                var UserName     = string.Empty;

                // get session information
                var Result = NativeMethods.NetSessionEnum(Computer, string.Empty, UserName, QueryLevel, out PtrInfo, -1, ref EntriesRead, ref TotalRead, ref ResumeHandle);

                // locate the offset of the initial intPtr
                var Offset = PtrInfo.ToInt64();

                // 0 = success
                if ((Result == 0) && (Offset > 0))
                {
                    // work out how much to increment the pointer by finding out the size of the structure
                    var Increment = Marshal.SizeOf(typeof(SESSION_INFO_10));

                    // parse all the result structures
                    for (var i = 0; (i < EntriesRead); i++)
                    {
                        // create a new int ptr at the given offset and cast the pointer as our result structure
                        var NewIntPtr = new System.IntPtr(Offset);
                        var Info      = (SESSION_INFO_10)Marshal.PtrToStructure(NewIntPtr, typeof(SESSION_INFO_10));

                        // return all the sections of the structure - have to do it this way for V2
                        var Session = new SessionInfo
                        {
                            ComputerName = Computer,
                            CName        = Info.sesi10_cname,
                            UserName     = Info.sesi10_username,
                            Time         = Info.sesi502_time,
                            IdleTime     = Info.sesi502_idle_time
                        };
                        Offset  = NewIntPtr.ToInt64();
                        Offset += Increment;
                        SessionInfos.Add(Session);
                    }

                    // free up the result buffer
                    NativeMethods.NetApiBufferFree(PtrInfo);
                }
                else
                {
                    Logger.Write_Verbose($@"[Get-NetSession] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");
                }
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(SessionInfos);
        }
예제 #12
0
        // the host enumeration block we're using to enumerate all servers
        private static IEnumerable <UserLocation> _Find_DomainUserLocation(string[] ComputerName, string[] TargetUsers, string CurrentUser, bool Stealth, bool CheckAccess, IntPtr TokenHandle)
        {
            var LogonToken = IntPtr.Zero;

            if (TokenHandle != IntPtr.Zero)
            {
                // impersonate the the token produced by LogonUser()/Invoke-UserImpersonation
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    TokenHandle = TokenHandle,
                    Quiet       = true
                });
            }

            var UserLocations = new List <UserLocation>();

            foreach (var TargetComputer in ComputerName)
            {
                var Up = TestConnection.Ping(TargetComputer, 1);
                if (Up)
                {
                    var Sessions = GetNetSession.Get_NetSession(new Args_Get_NetSession {
                        ComputerName = new[] { TargetComputer }
                    });
                    foreach (var Session in Sessions)
                    {
                        var UserName = Session.UserName;
                        var CName    = Session.CName;

                        if (!CName.IsNullOrEmpty() && CName.StartsWith(@"\\"))
                        {
                            CName = CName.TrimStart('\\');
                        }

                        // make sure we have a result, and ignore computer$ sessions
                        if ((UserName != null) && (UserName.Trim() != "") && (!UserName.IsRegexMatch(CurrentUser)) && (!UserName.IsRegexMatch(@"\$$")))
                        {
                            if ((TargetUsers == null) || (TargetUsers.Contains(UserName)))
                            {
                                var UserLocation = new UserLocation
                                {
                                    UserDomain   = null,
                                    UserName     = UserName,
                                    ComputerName = TargetComputer,
                                    SessionFrom  = CName
                                };

                                // try to resolve the DNS hostname of $Cname
                                try
                                {
                                    var CNameDNSName = System.Net.Dns.GetHostEntry(CName).HostName;
                                    UserLocation.SessionFromName = CNameDNSName;
                                }
                                catch
                                {
                                    UserLocation.SessionFromName = null;
                                }

                                // see if we're checking to see if we have local admin access on this machine
                                if (CheckAccess)
                                {
                                    var Admin = TestAdminAccess.Test_AdminAccess(new Args_Test_AdminAccess {
                                        ComputerName = new[] { CName }
                                    }).FirstOrDefault();
                                    UserLocation.LocalAdmin = Admin != null ? Admin.IsAdmin : false;
                                }
                                else
                                {
                                    UserLocation.LocalAdmin = false;
                                }
                                UserLocations.Add(UserLocation);
                            }
                        }
                    }
                    if (!Stealth)
                    {
                        // if we're not 'stealthy', enumerate loggedon users as well
                        var LoggedOn = GetNetLoggedon.Get_NetLoggedon(new Args_Get_NetLoggedon {
                            ComputerName = new[] { TargetComputer }
                        });
                        foreach (var User in LoggedOn)
                        {
                            var UserName   = User.UserName;
                            var UserDomain = User.LogonDomain;

                            // make sure wet have a result
                            if ((UserName != null) && (UserName.Trim() != ""))
                            {
                                if ((TargetUsers == null) || (TargetUsers.Contains(UserName)) && (!UserName.IsRegexMatch(@"\$$")))
                                {
                                    var IPAddress = ResolveIPAddress.Resolve_IPAddress(new Args_Resolve_IPAddress {
                                        ComputerName = new[] { TargetComputer }
                                    }).FirstOrDefault()?.IPAddress;
                                    var UserLocation = new UserLocation
                                    {
                                        UserDomain      = UserDomain,
                                        UserName        = UserName,
                                        ComputerName    = TargetComputer,
                                        IPAddress       = IPAddress,
                                        SessionFrom     = null,
                                        SessionFromName = null
                                    };

                                    // see if we're checking to see if we have local admin access on this machine
                                    if (CheckAccess)
                                    {
                                        var Admin = TestAdminAccess.Test_AdminAccess(new Args_Test_AdminAccess {
                                            ComputerName = new[] { TargetComputer }
                                        }).FirstOrDefault();
                                        UserLocation.LocalAdmin = Admin.IsAdmin;
                                    }
                                    else
                                    {
                                        UserLocation.LocalAdmin = false;
                                    }
                                    UserLocations.Add(UserLocation);
                                }
                            }
                        }
                    }
                }
            }

            if (TokenHandle != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(UserLocations);
        }
예제 #13
0
        // the host enumeration block we're using to enumerate all servers

        private static IEnumerable <ShareInfo> _Find_DomainShare(string[] ComputerName, bool CheckShareAccess, IntPtr TokenHandle)
        {
            var LogonToken = IntPtr.Zero;

            if (TokenHandle != IntPtr.Zero)
            {
                // impersonate the the token produced by LogonUser()/Invoke-UserImpersonation
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    TokenHandle = TokenHandle,
                    Quiet       = true
                });
            }

            var DomainShares = new List <ShareInfo>();

            foreach (var TargetComputer in ComputerName)
            {
                var Up = TestConnection.Ping(TargetComputer, 1);
                if (Up)
                {
                    // get the shares for this host and check what we find

                    var Shares = GetNetShare.Get_NetShare(new Args_Get_NetShare
                    {
                        ComputerName = new[] { TargetComputer }
                    });

                    foreach (var Share in Shares)
                    {
                        var ShareName = Share.Name;
                        // $Remark = $Share.Remark
                        var Path = @"\\" + TargetComputer + @"\" + ShareName;
                        if ((!string.IsNullOrEmpty(ShareName)) && (ShareName.Trim() != ""))
                        {
                            // see if we want to check access to this share
                            if (CheckShareAccess)
                            {
                                // check if the user has access to this path
                                try
                                {
                                    Directory.GetFiles(Path);
                                    DomainShares.Add(Share);
                                }
                                catch (Exception e)
                                {
                                    Logger.Write_Verbose($@"Error accessing share path {Path} : {e}");
                                }
                            }
                            else
                            {
                                DomainShares.Add(Share);
                            }
                        }
                    }
                }
            }

            if (TokenHandle != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(DomainShares);
        }
예제 #14
0
        public static IEnumerable <ComputerSite> Get_NetComputerSiteName(Args_Get_NetComputerSiteName args = null)
        {
            if (args == null)
            {
                args = new Args_Get_NetComputerSiteName();
            }
            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation {
                    Credential = args.Credential
                });
            }

            var ComputerSites = new List <ComputerSite>();

            foreach (var item in args.ComputerName)
            {
                string IPAddress;
                var    Computer = item;
                //if we get an IP address, try to resolve the IP to a hostname
                if (Computer.IsRegexMatch(@"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$"))
                {
                    IPAddress = Computer;
                    Computer  = System.Net.Dns.GetHostEntry(Computer).HostName;
                }
                else
                {
                    IPAddress = ResolveIPAddress.Resolve_IPAddress(new Args_Resolve_IPAddress {
                        ComputerName = new[] { Computer }
                    }).First().IPAddress;
                }

                var PtrInfo = IntPtr.Zero;

                var Result = NativeMethods.DsGetSiteName(Computer, out PtrInfo);

                var ComputerSite = new ComputerSite
                {
                    ComputerName = Computer,
                    IPAddress    = IPAddress
                };

                if (Result == 0)
                {
                    var Sitename = System.Runtime.InteropServices.Marshal.PtrToStringAuto(PtrInfo);
                    ComputerSite.SiteName = Sitename;
                }
                else
                {
                    Logger.Write_Verbose($@"[Get-NetComputerSiteName] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");

                    ComputerSite.SiteName = @"";
                }

                // free up the result buffer
                NativeMethods.NetApiBufferFree(PtrInfo);

                ComputerSites.Add(ComputerSite);
            }
            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(ComputerSites);
        }
예제 #15
0
        public static IEnumerable <UserLocation> Find_DomainUserLocation(Args_Find_DomainUserLocation args = null)
        {
            if (args == null)
            {
                args = new Args_Find_DomainUserLocation();
            }

            var ComputerSearcherArguments = new Args_Get_DomainComputer
            {
                Properties      = new[] { "dnshostname" },
                Domain          = args.Domain,
                LDAPFilter      = args.ComputerLDAPFilter,
                SearchBase      = args.ComputerSearchBase,
                Unconstrained   = args.Unconstrained,
                OperatingSystem = args.OperatingSystem,
                ServicePack     = args.ServicePack,
                SiteName        = args.SiteName,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            if (!string.IsNullOrEmpty(args.ComputerDomain))
            {
                ComputerSearcherArguments.Domain = args.ComputerDomain;
            }

            var UserSearcherArguments = new Args_Get_DomainUser
            {
                Properties      = new[] { "samaccountname" },
                Identity        = args.UserIdentity,
                Domain          = args.Domain,
                LDAPFilter      = args.UserLDAPFilter,
                SearchBase      = args.UserSearchBase,
                AdminCount      = args.UserAdminCount,
                AllowDelegation = args.AllowDelegation,
                Server          = args.Server,
                SearchScope     = args.SearchScope,
                ResultPageSize  = args.ResultPageSize,
                ServerTimeLimit = args.ServerTimeLimit,
                Tombstone       = args.Tombstone,
                Credential      = args.Credential
            };

            if (!string.IsNullOrEmpty(args.UserDomain))
            {
                UserSearcherArguments.Domain = args.UserDomain;
            }

            string[] TargetComputers = null;

            // first, build the set of computers to enumerate
            if (args.ComputerName != null)
            {
                TargetComputers = args.ComputerName;
            }
            else
            {
                if (args.Stealth)
                {
                    Logger.Write_Verbose($@"[Find-DomainUserLocation] Stealth enumeration using source: {args.StealthSource}");
                    var TargetComputerArrayList = new System.Collections.ArrayList();

                    if (args.StealthSource.ToString().IsRegexMatch("File|All"))
                    {
                        Logger.Write_Verbose("[Find-DomainUserLocation] Querying for file servers");
                        var FileServerSearcherArguments = new Args_Get_DomainFileServer
                        {
                            Domain          = new[] { args.Domain },
                            SearchBase      = args.ComputerSearchBase,
                            Server          = args.Server,
                            SearchScope     = args.SearchScope,
                            ResultPageSize  = args.ResultPageSize,
                            ServerTimeLimit = args.ServerTimeLimit,
                            Tombstone       = args.Tombstone,
                            Credential      = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            FileServerSearcherArguments.Domain = new[] { args.ComputerDomain }
                        }
                        ;
                        var FileServers = GetDomainFileServer.Get_DomainFileServer(FileServerSearcherArguments);
                        TargetComputerArrayList.AddRange(FileServers);
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DFS|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for DFS servers");
                        // { TODO: fix the passed parameters to Get-DomainDFSShare
                        // $ComputerName += Get-DomainDFSShare -Domain $Domain -Server $DomainController | ForEach-Object {$_.RemoteServerName}
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DC|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for domain controllers");
                        var DCSearcherArguments = new Args_Get_DomainController
                        {
                            LDAP       = true,
                            Domain     = args.Domain,
                            Server     = args.Server,
                            Credential = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            DCSearcherArguments.Domain = args.ComputerDomain;
                        }
                        var DomainControllers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
                        TargetComputerArrayList.AddRange(DomainControllers);
                    }
                    TargetComputers = TargetComputerArrayList.ToArray() as string[];
                }
            }
            if (args.ComputerName != null)
            {
                TargetComputers = args.ComputerName;
            }
            else
            {
                if (args.Stealth)
                {
                    Logger.Write_Verbose($@"[Find-DomainUserLocation] Stealth enumeration using source: {args.StealthSource}");
                    var TargetComputerArrayList = new System.Collections.ArrayList();

                    if (args.StealthSource.ToString().IsRegexMatch("File|All"))
                    {
                        Logger.Write_Verbose("[Find-DomainUserLocation] Querying for file servers");
                        var FileServerSearcherArguments = new Args_Get_DomainFileServer
                        {
                            Domain          = new[] { args.Domain },
                            SearchBase      = args.ComputerSearchBase,
                            Server          = args.Server,
                            SearchScope     = args.SearchScope,
                            ResultPageSize  = args.ResultPageSize,
                            ServerTimeLimit = args.ServerTimeLimit,
                            Tombstone       = args.Tombstone,
                            Credential      = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            FileServerSearcherArguments.Domain = new[] { args.ComputerDomain }
                        }
                        ;
                        var FileServers = GetDomainFileServer.Get_DomainFileServer(FileServerSearcherArguments);
                        TargetComputerArrayList.AddRange(FileServers);
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DFS|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for DFS servers");
                        // { TODO: fix the passed parameters to Get-DomainDFSShare
                        // $ComputerName += Get-DomainDFSShare -Domain $Domain -Server $DomainController | ForEach-Object {$_.RemoteServerName}
                    }
                    if (args.StealthSource.ToString().IsRegexMatch("DC|All"))
                    {
                        Logger.Write_Verbose(@"[Find-DomainUserLocation] Querying for domain controllers");
                        var DCSearcherArguments = new Args_Get_DomainController
                        {
                            LDAP       = true,
                            Domain     = args.Domain,
                            Server     = args.Server,
                            Credential = args.Credential
                        };
                        if (!string.IsNullOrEmpty(args.ComputerDomain))
                        {
                            DCSearcherArguments.Domain = args.ComputerDomain;
                        }
                        var DomainControllers = GetDomainController.Get_DomainController(DCSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
                        TargetComputerArrayList.AddRange(DomainControllers);
                    }
                    TargetComputers = TargetComputerArrayList.ToArray() as string[];
                }
                else
                {
                    Logger.Write_Verbose("[Find-DomainUserLocation] Querying for all computers in the domain");
                    TargetComputers = GetDomainComputer.Get_DomainComputer(ComputerSearcherArguments).Select(x => (x as LDAPProperty).dnshostname).ToArray();
                }
            }
            Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetComputers length: {TargetComputers.Length}");
            if (TargetComputers.Length == 0)
            {
                throw new Exception("[Find-DomainUserLocation] No hosts found to enumerate");
            }

            // get the current user so we can ignore it in the results
            string CurrentUser;

            if (args.Credential != null)
            {
                CurrentUser = args.Credential.UserName;
            }
            else
            {
                CurrentUser = Environment.UserName.ToLower();
            }

            // now build the user target set
            string[] TargetUsers = null;
            if (args.ShowAll)
            {
                TargetUsers = new string[] { };
            }
            else if (args.UserIdentity != null || args.UserLDAPFilter != null || args.UserSearchBase != null || args.UserAdminCount || args.UserAllowDelegation)
            {
                TargetUsers = GetDomainUser.Get_DomainUser(UserSearcherArguments).Select(x => (x as LDAPProperty).samaccountname).ToArray();
            }
            else
            {
                var GroupSearcherArguments = new Args_Get_DomainGroupMember
                {
                    Identity        = args.UserGroupIdentity,
                    Recurse         = true,
                    Domain          = args.UserDomain,
                    SearchBase      = args.UserSearchBase,
                    Server          = args.Server,
                    SearchScope     = args.SearchScope,
                    ResultPageSize  = args.ResultPageSize,
                    ServerTimeLimit = args.ServerTimeLimit,
                    Tombstone       = args.Tombstone,
                    Credential      = args.Credential
                };
                TargetUsers = GetDomainGroupMember.Get_DomainGroupMember(GroupSearcherArguments).Select(x => x.MemberName).ToArray();
            }

            Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetUsers length: {TargetUsers.Length}");
            if ((!args.ShowAll) && (TargetUsers.Length == 0))
            {
                throw new Exception("[Find-DomainUserLocation] No users found to target");
            }

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                if (args.Delay != 0 || args.StopOnSuccess)
                {
                    LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                    {
                        Credential = args.Credential
                    });
                }
                else
                {
                    LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                    {
                        Credential = args.Credential,
                        Quiet      = true
                    });
                }
            }

            var rets = new List <UserLocation>();

            // only ignore threading if -Delay is passed
            if (args.Delay != 0 /* || args.StopOnSuccess*/)
            {
                Logger.Write_Verbose($@"[Find-DomainUserLocation] Total number of hosts: {TargetComputers.Count()}");
                Logger.Write_Verbose($@"[Find-DomainUserLocation] Delay: {args.Delay}, Jitter: {args.Jitter}");

                var Counter = 0;
                var RandNo  = new System.Random();

                foreach (var TargetComputer in TargetComputers)
                {
                    Counter = Counter + 1;

                    // sleep for our semi-randomized interval
                    System.Threading.Thread.Sleep(RandNo.Next((int)((1 - args.Jitter) * args.Delay), (int)((1 + args.Jitter) * args.Delay)) * 1000);

                    Logger.Write_Verbose($@"[Find-DomainUserLocation] Enumerating server {TargetComputer} ({Counter} of {TargetComputers.Count()})");
                    var Result = _Find_DomainUserLocation(new[] { TargetComputer }, TargetUsers, CurrentUser, args.Stealth, args.CheckAccess, LogonToken);
                    if (Result != null)
                    {
                        rets.AddRange(Result);
                    }
                    if (Result != null && args.StopOnSuccess)
                    {
                        Logger.Write_Verbose("[Find-DomainUserLocation] Target user found, returning early");
                        return(rets);
                    }
                }
            }
            else
            {
                Logger.Write_Verbose($@"[Find-DomainUserLocation] Using threading with threads: {args.Threads}");
                Logger.Write_Verbose($@"[Find-DomainUserLocation] TargetComputers length: {TargetComputers.Length}");

                // if we're using threading, kick off the script block with New-ThreadedFunction
                // if we're using threading, kick off the script block with New-ThreadedFunction using the $HostEnumBlock + params
                System.Threading.Tasks.Parallel.ForEach(
                    TargetComputers,
                    TargetComputer =>
                {
                    var Result = _Find_DomainUserLocation(new[] { TargetComputer }, TargetUsers, CurrentUser, args.Stealth, args.CheckAccess, LogonToken);
                    lock (rets)
                    {
                        if (Result != null)
                        {
                            rets.AddRange(Result);
                        }
                    }
                });
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(rets);
        }
예제 #16
0
        public static IEnumerable <LoggedOnUserInfo> Get_NetLoggedon(Args_Get_NetLoggedon args = null)
        {
            if (args == null)
            {
                args = new Args_Get_NetLoggedon();
            }

            var LogonToken = IntPtr.Zero;

            if (args.Credential != null)
            {
                LogonToken = InvokeUserImpersonation.Invoke_UserImpersonation(new Args_Invoke_UserImpersonation
                {
                    Credential = args.Credential
                });
            }

            var LoggedOns = new List <LoggedOnUserInfo>();

            foreach (var Computer in args.ComputerName)
            {
                // declare the reference variables
                var QueryLevel   = 1;
                var PtrInfo      = IntPtr.Zero;
                var EntriesRead  = 0;
                var TotalRead    = 0;
                var ResumeHandle = 0;

                // get logged on user information
                var Result = NativeMethods.NetWkstaUserEnum(Computer, QueryLevel, out PtrInfo, -1, out EntriesRead, out TotalRead, ref ResumeHandle);

                // locate the offset of the initial intPtr
                var Offset = PtrInfo.ToInt64();

                // 0 = success
                if ((Result == 0) && (Offset > 0))
                {
                    // work out how much to increment the pointer by finding out the size of the structure
                    var Increment = Marshal.SizeOf(typeof(WKSTA_USER_INFO_1));

                    // parse all the result structures
                    for (var i = 0; (i < EntriesRead); i++)
                    {
                        // create a new int ptr at the given offset and cast the pointer as our result structure
                        var NewIntPtr = new System.IntPtr(Offset);
                        var Info      = (WKSTA_USER_INFO_1)Marshal.PtrToStructure(NewIntPtr, typeof(WKSTA_USER_INFO_1));

                        // return all the sections of the structure - have to do it this way for V2
                        LoggedOns.Add(new LoggedOnUserInfo
                        {
                            UserName     = Info.wkui1_username,
                            LogonDomain  = Info.wkui1_logon_domain,
                            AuthDomains  = Info.wkui1_oth_domains,
                            LogonServer  = Info.wkui1_logon_server,
                            ComputerName = Computer
                        });
                        Offset  = NewIntPtr.ToInt64();
                        Offset += Increment;
                    }

                    // free up the result buffer
                    NativeMethods.NetApiBufferFree(PtrInfo);
                }
                else
                {
                    Logger.Write_Verbose($@"[Get-NetLoggedon] Error: {new System.ComponentModel.Win32Exception((int)Result).Message}");
                }
            }

            if (LogonToken != IntPtr.Zero)
            {
                InvokeRevertToSelf.Invoke_RevertToSelf(LogonToken);
            }
            return(LoggedOns);
        }