예제 #1
0
        /// <summary>
        /// Wraps the NetWkstaUserEnum API call in a timeout
        /// </summary>
        /// <param name="computer"></param>
        /// <returns></returns>
        private static async Task <List <Session> > GetLoggedOnUsersAPI(Computer computer)
        {
            var resumeHandle        = 0;
            var workstationInfoType = typeof(WKSTA_USER_INFO_1);
            var ptrInfo             = IntPtr.Zero;
            var entriesRead         = 0;
            var sessionList         = new List <Session>();

            try
            {
                var task = Task.Run(() => NetWkstaUserEnum(computer.APIName, 1, out ptrInfo,
                                                           -1, out entriesRead, out _, ref resumeHandle));

                if (await Task.WhenAny(task, Task.Delay(10000)) != task)
                {
                    if (Options.Instance.DumpComputerStatus)
                    {
                        OutputTasks.AddComputerStatus(new ComputerStatus
                        {
                            ComputerName = computer.DisplayName,
                            Status       = "Timeout",
                            Task         = "NetWkstaUserEnum"
                        });
                    }

                    return(sessionList);
                }

                var taskResult = task.Result;
                //Check the result of the task. 234 and 0 are both acceptable.
                if (taskResult != 0 && taskResult != 234)
                {
                    if (Options.Instance.DumpComputerStatus)
                    {
                        OutputTasks.AddComputerStatus(new ComputerStatus
                        {
                            ComputerName = computer.DisplayName,
                            Status       = ((NetApiStatus)taskResult).ToString(),
                            Task         = "NetWkstaUserEnum"
                        });
                    }
                    return(sessionList);
                }

                var iterator = ptrInfo;

                if (Options.Instance.DumpComputerStatus)
                {
                    OutputTasks.AddComputerStatus(new ComputerStatus
                    {
                        ComputerName = computer.DisplayName,
                        Status       = "Success",
                        Task         = "NetWkstaUserEnum"
                    });
                }

                for (var i = 0; i < entriesRead; i++)
                {
                    var data = (WKSTA_USER_INFO_1)Marshal.PtrToStructure(iterator, workstationInfoType);
                    iterator = (IntPtr)(iterator.ToInt64() + Marshal.SizeOf(workstationInfoType));

                    var domain   = data.wkui1_logon_domain;
                    var username = data.wkui1_username;

                    //Remove local accounts
                    if (domain.Equals(computer.SamAccountName, StringComparison.CurrentCultureIgnoreCase))
                    {
                        continue;
                    }

                    //Remove blank accounts and computer accounts
                    if (username.Trim() == "" || username.EndsWith("$") || username == "ANONYMOUS LOGON" || username == Options.Instance.CurrentUserName)
                    {
                        continue;
                    }

                    //Any domain with a space is unusable (ex: NT AUTHORITY, FONT DRIVER HOST)
                    if (domain.Contains(" "))
                    {
                        continue;
                    }

                    var(rSuccess, sid, _) = await ResolutionHelpers.ResolveAccountNameToSidAndType(username, domain);

                    if (rSuccess)
                    {
                        sessionList.Add(new Session
                        {
                            UserId     = sid,
                            ComputerId = computer.ObjectIdentifier
                        });
                    }
                    else
                    {
                        sessionList.Add(new Session
                        {
                            UserId     = $"{username}@{Helpers.NormalizeDomainName(domain)}".ToUpper(),
                            ComputerId = computer.ObjectIdentifier
                        });
                    }
                }

                return(sessionList);
            }
            finally
            {
                if (ptrInfo != IntPtr.Zero)
                {
                    NetApiBufferFree(ptrInfo);
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Wraps the NetSessionEnum API call with a timeout and parses the results
        /// </summary>
        /// <param name="computer"></param>
        /// <returns></returns>
        private static async Task <List <Session> > GetNetSessions(Computer computer)
        {
            var resumeHandle    = IntPtr.Zero;
            var sessionInfoType = typeof(SESSION_INFO_10);

            var entriesRead = 0;
            var ptrInfo     = IntPtr.Zero;

            var sessionList = new List <Session>();

            try
            {
                var task = Task.Run(() => NetSessionEnum(computer.APIName, null, null, 10,
                                                         out ptrInfo, -1, out entriesRead, out _, ref resumeHandle));

                //10 second timeout
                if (await Task.WhenAny(task, Task.Delay(10000)) != task)
                {
                    if (Options.Instance.DumpComputerStatus)
                    {
                        OutputTasks.AddComputerStatus(new ComputerStatus
                        {
                            ComputerName = computer.DisplayName,
                            Status       = "Timeout",
                            Task         = "NetSessionEnum"
                        });
                    }
                    return(sessionList);
                }

                var taskResult = task.Result;

                if (taskResult != 0)
                {
                    if (Options.Instance.DumpComputerStatus)
                    {
                        OutputTasks.AddComputerStatus(new ComputerStatus
                        {
                            ComputerName = computer.DisplayName,
                            Status       = ((NetApiStatus)taskResult).ToString(),
                            Task         = "NetSessionEnum"
                        });
                    }
                    return(sessionList);
                }

                var sessions = new SESSION_INFO_10[entriesRead];
                var iterator = ptrInfo;

                for (var i = 0; i < entriesRead; i++)
                {
                    sessions[i] = (SESSION_INFO_10)Marshal.PtrToStructure(iterator, sessionInfoType);
                    iterator    = (IntPtr)(iterator.ToInt64() + Marshal.SizeOf(sessionInfoType));
                }

                if (Options.Instance.DumpComputerStatus)
                {
                    OutputTasks.AddComputerStatus(new ComputerStatus
                    {
                        ComputerName = computer.DisplayName,
                        Status       = "Success",
                        Task         = "NetSessionEnum"
                    });
                }

                foreach (var session in sessions)
                {
                    var sessionUsername = session.sesi10_username;
                    var computerName    = session.sesi10_cname;

                    if (computerName == null)
                    {
                        continue;
                    }

                    string computerSid = null;

                    //Filter out computer accounts, Anonymous Logon, empty users
                    if (sessionUsername.EndsWith(
                            "$") || sessionUsername.Trim() == "" || sessionUsername == "$" || sessionUsername ==
                        Options.Instance.CurrentUserName || sessionUsername == "ANONYMOUS LOGON")
                    {
                        continue;
                    }

                    //Remove leading backslashes
                    if (computerName.StartsWith("\\"))
                    {
                        computerName = computerName.TrimStart('\\');
                    }

                    //Remove empty sessions
                    if (string.IsNullOrEmpty(computerName))
                    {
                        continue;
                    }

                    //If the session is pointing to localhost, we already know what the SID of the computer is
                    if (computerName.Equals("[::1]") || computerName.Equals("127.0.0.1"))
                    {
                        computerSid = computer.ObjectIdentifier;
                    }

                    //Try converting the computer name to a SID if we didn't already get it from a localhost
                    computerSid = computerSid ?? await ResolutionHelpers.ResolveHostToSid(computerName, computer.Domain);

                    //Try converting the username to a SID
                    var searcher = Helpers.GetDirectorySearcher(computer.Domain);
                    var sids     = await searcher.LookupUserInGC(sessionUsername);

                    if (sids?.Length > 0)
                    {
                        foreach (var sid in sids)
                        {
                            sessionList.Add(new Session
                            {
                                ComputerId = computerSid,
                                UserId     = sid
                            });
                        }
                    }
                    else
                    {
                        var(success, sid, _) =
                            await ResolutionHelpers.ResolveAccountNameToSidAndType(sessionUsername, computer.Domain);

                        if (success)
                        {
                            sessionList.Add(new Session
                            {
                                ComputerId = computerSid,
                                UserId     = sid
                            });
                        }
                        else
                        {
                            sessionList.Add(new Session
                            {
                                ComputerId = computerSid,
                                UserId     = sessionUsername
                            });
                        }
                    }
                }

                return(sessionList);
            }
            finally
            {
                if (ptrInfo != IntPtr.Zero)
                {
                    NetApiBufferFree(ptrInfo);
                }
            }
        }