public static IEnumerable <Session> GetNetSessions(ResolvedEntry target, string computerDomain) { if (!Utils.IsMethodSet(ResolvedCollectionMethod.Session) && !Utils.IsMethodSet(ResolvedCollectionMethod.SessionLoop)) { yield break; } var resumeHandle = IntPtr.Zero; var si10 = typeof(SESSION_INFO_10); var entriesRead = 0; var ptrInfo = IntPtr.Zero; var t = Task <int> .Factory.StartNew(() => NetSessionEnum(target.BloodHoundDisplay, null, null, 10, out ptrInfo, -1, out entriesRead, out _, ref resumeHandle)); var success = t.Wait(Timeout); if (!success) { throw new TimeoutException(); } var returnValue = t.Result; Utils.Debug($"EntriesRead from NetSessionEnum: {entriesRead}"); Utils.Debug($"ReturnValue from NetSessionEnum: {returnValue}"); //If we don't get a success, just break if (returnValue != (int)NERR.NERR_Success) { yield break; } var results = new SESSION_INFO_10[entriesRead]; var iter = ptrInfo; //Loop over the data and store it into an array for (var i = 0; i < entriesRead; i++) { results[i] = (SESSION_INFO_10)Marshal.PtrToStructure(iter, si10); iter = (IntPtr)(iter.ToInt64() + Marshal.SizeOf(si10)); } //Free the IntPtr NetApiBufferFree(ptrInfo); foreach (var result in results) { var username = result.sesi10_username; var cname = result.sesi10_cname; Utils.Debug($"Result Username: {username}"); Utils.Debug($"Result cname: {cname}"); if (cname == null || username.EndsWith("$") || username.Trim() == "" || username == "$" || username == _options.CurrentUser) { continue; } if (cname.StartsWith("\\", StringComparison.CurrentCulture)) { cname = cname.TrimStart('\\'); } if (cname.Equals("[::1]") || cname.Equals("127.0.0.1")) { cname = target.BloodHoundDisplay; } var dnsHostName = _utils.ResolveHost(cname); Utils.Debug($"Result cname: {dnsHostName}"); if (dnsHostName == null) { continue; } //If we're skipping Global Catalog deconfliction, just return a session if (_options.SkipGcDeconfliction) { yield return(new Session { ComputerName = dnsHostName, UserName = username, Weight = 2 }); } else { //Check our cache first if (!_cache.GetGcMap(username, out var possible) || possible == null) { //If we didn't get a cache hit, search the global catalog var temp = new List <string>(); foreach (var entry in _utils.DoSearch( $"(&(samAccountType=805306368)(samaccountname={username}))", SearchScope.Subtree, new[] { "distinguishedname" }, computerDomain, "", true)) { temp.Add(Utils.ConvertDnToDomain(entry.DistinguishedName).ToUpper()); } possible = temp.ToArray(); _cache.AddGcMap(username, possible); } switch (possible.Length) { case 0: //Object isn't in GC, so we'll default to the computer's domain yield return(new Session { UserName = $"{username}@{computerDomain}", ComputerName = dnsHostName, Weight = 2 }); break; case 1: //Exactly one instance of this samaccountname, the best scenario yield return(new Session { UserName = $"{username}@{possible.First()}", ComputerName = dnsHostName, Weight = 2 }); break; default: //Multiple possibilities (whyyyyy) //Add a weight of 1 for same domain as computer, 2 for others foreach (var possibility in possible) { var weight = possibility.Equals(computerDomain, StringComparison.CurrentCultureIgnoreCase) ? 1 : 2; yield return(new Session { Weight = weight, ComputerName = dnsHostName.ToUpper(), UserName = $"{username}@{possibility}" }); } break; } } } Utils.DoJitter(); }
private void fill_netserver_page() { try { SERVER_INFO_102 serv_info = WinApiNETwrapper.GetServerInfo_102(resource_intern.lpRemoteName); textBoxNetserverPlatformId.Text = serv_info.sv102_platform_id.ToString(); textBoxNetserverSoftwareType.Text = IOhelper.NetserverTypeToString(serv_info.sv102_type); textBoxPlatformVersion.Text = string.Format("{0}.{1}", serv_info.GetVersionMajor(), serv_info.sv102_version_minor); textBoxNetserverMaxUsers.Text = serv_info.sv102_users.ToString(); textBoxNetserverDisconnectTime.Text = serv_info.sv102_disc.ToString(); textBoxNetserverAnnounceTime.Text = serv_info.sv102_announce.ToString(); textBoxNetserverUsersPerLicense.Text = serv_info.sv102_licenses.ToString(); textBoxNetserverUserPath.Text = serv_info.sv102_userpath; } catch (Exception ex) { errorProvider1.SetIconAlignment(textBoxNetserverPlatformId, ErrorIconAlignment.MiddleLeft); errorProvider1.SetError(textBoxNetserverPlatformId, ex.Message); } try { NetRemoteComputerSupportsFeatures features = WinApiNETwrapper.GetComputerSupports(resource_intern.lpRemoteName); textBoxNetserverFeatures.Text = features.ToString(); } catch (Exception ex) { errorProvider1.SetIconAlignment(textBoxNetserverFeatures, ErrorIconAlignment.MiddleLeft); errorProvider1.SetError(textBoxNetserverFeatures, ex.Message); } try { TIME_OF_DAY_INFO dt = WinApiNETwrapper.GetServerTime(resource_intern.lpRemoteName); textBoxNetserverDatetime.Text = string.Format("{0} {1},{2}", dt.GetCurrentDatetime().ToLongDateString(), dt.GetCurrentDatetime().ToLongTimeString(), dt.GetCurrentDatetime().Millisecond); textBoxNetserverUptime.Text = dt.GetUptime().ToString(); } catch (Exception ex) { errorProvider1.SetIconAlignment(textBoxNetserverDatetime, ErrorIconAlignment.MiddleLeft); errorProvider1.SetError(textBoxNetserverDatetime, ex.Message); } //NET_DISPLAY_GROUP[] groups = WinApiNETwrapper.QueryDisplayInfoGroup(resource_intern.lpRemoteName); //NET_DISPLAY_MACHINE[] machines = WinApiNETwrapper.QueryDisplayInfoMachine(resource_intern.lpRemoteName); //NET_DISPLAY_USER[] users = WinApiNETwrapper.QueryDisplayInfoUser(resource_intern.lpRemoteName); try { SERVER_TRANSPORT_INFO_1[] transports = WinApiNETwrapper.ServerTransportEnum_1(resource_intern.lpRemoteName); for (int i = 0; i < transports.Length; i++) { ListViewItem lvi = new ListViewItem(); lvi.Text = transports[i].svti1_transportname; lvi.SubItems.Add(transports[i].TransportAddress); lvi.SubItems.Add(transports[i].svti1_networkaddress); lvi.SubItems.Add(transports[i].svti1_domain); lvi.SubItems.Add(transports[i].svti1_numberofvcs.ToString()); listViewTransports.Items.Add(lvi); } listViewTransports.Dock = DockStyle.Fill; } catch (Exception ex) { errorProvider1.SetIconAlignment(listViewTransports, ErrorIconAlignment.MiddleLeft); errorProvider1.SetError(listViewTransports, ex.Message); } /* net sessions */ errorProvider1.SetIconAlignment(listViewSessions, ErrorIconAlignment.MiddleLeft); Array sessions = null; NetSessionEnumLevel session_level = NetSessionEnumLevel.INFO_502; try { //try level 502 sessions = WinApiNETwrapper.NetSessionEnum(resource_intern.lpRemoteName, null, null, session_level); } catch (Exception) { //if exception try level 10 session_level = NetSessionEnumLevel.INFO_10; try { sessions = WinApiNETwrapper.NetSessionEnum(resource_intern.lpRemoteName, null, null, session_level); } catch (Exception ex_10) { errorProvider1.SetError(listViewSessions, ex_10.Message); } } if (sessions != null) { listViewSessions.Dock = DockStyle.Fill; for (int i = 0; i < sessions.Length; i++) { ListViewItem lvi = new ListViewItem(); switch (session_level) { case NetSessionEnumLevel.INFO_502: SESSION_INFO_502 info_502 = (SESSION_INFO_502)sessions.GetValue(i); lvi.Text = info_502.sesi502_cname; lvi.SubItems.Add(info_502.sesi502_username); lvi.SubItems.Add(info_502.sesi502_num_opens.ToString()); lvi.SubItems.Add(info_502.TimeActive.ToString()); lvi.SubItems.Add(info_502.TimeIdle.ToString()); lvi.SubItems.Add(info_502.sesi502_user_flags.ToString()); lvi.SubItems.Add(info_502.sesi502_cltype_name); lvi.SubItems.Add(info_502.sesi502_transport); break; case NetSessionEnumLevel.INFO_10: SESSION_INFO_10 info_10 = (SESSION_INFO_10)sessions.GetValue(i); lvi.Text = info_10.sesi10_cname; lvi.SubItems.Add(string.Empty); lvi.SubItems.Add(string.Empty); lvi.SubItems.Add(info_10.TimeActive.ToString()); lvi.SubItems.Add(info_10.TimeIdle.ToString()); lvi.SubItems.Add(string.Empty); lvi.SubItems.Add(string.Empty); lvi.SubItems.Add(string.Empty); break; } listViewSessions.Items.Add(lvi); } } /* end of net sessions */ /* open files */ try { Array files = WinApiNETwrapper.NetFileEnum(resource_intern.lpRemoteName, null, null, NetFileEnumLevel.INFO_3); listViewFiles.Dock = DockStyle.Fill; for (int i = 0; i < files.Length; i++) { FILE_INFO_3 f_info = (FILE_INFO_3)files.GetValue(i); ListViewItem lvi = new ListViewItem(); lvi.Text = string.Format("0x{0:X}", f_info.fi3_id); lvi.SubItems.Add(f_info.fi3_permission.ToString()); lvi.SubItems.Add(f_info.fi3_num_locks.ToString()); lvi.SubItems.Add(f_info.fi3_pathname); lvi.SubItems.Add(f_info.fi3_username); listViewFiles.Items.Add(lvi); } } catch (Exception ex_files) { errorProvider1.SetIconAlignment(listViewFiles, ErrorIconAlignment.MiddleLeft); errorProvider1.SetError(listViewFiles, ex_files.Message); } /* end of open files */ }
public static IEnumerable <Session> GetNetSessions(ResolvedEntry target, string computerDomain) { var resumeHandle = IntPtr.Zero; var si10 = typeof(SESSION_INFO_10); var entriesRead = 0; var ptrInfo = IntPtr.Zero; var t = Task <int> .Factory.StartNew(() => NetSessionEnum(target.BloodHoundDisplay, null, null, 10, out ptrInfo, -1, out entriesRead, out int _, ref resumeHandle)); var success = t.Wait(Timeout); if (!success) { throw new TimeoutException(); } var returnValue = t.Result; //If we don't get a success, just break if (returnValue != (int)NERR.NERR_Success) { yield break; } var results = new SESSION_INFO_10[entriesRead]; var iter = ptrInfo; //Loop over the data and store it into an array for (var i = 0; i < entriesRead; i++) { results[i] = (SESSION_INFO_10)Marshal.PtrToStructure(iter, si10); iter = (IntPtr)(iter.ToInt64() + Marshal.SizeOf(si10)); } //Free the IntPtr NetApiBufferFree(ptrInfo); foreach (var result in results) { var username = result.sesi10_username; var cname = result.sesi10_cname; if (cname == null || username.EndsWith("$") || username.Trim() == "" || username == "$" || username == _options.CurrentUser) { continue; } if (cname.StartsWith("\\", StringComparison.CurrentCulture)) { cname = cname.TrimStart('\\'); } if (cname.Equals("[::1]") || cname.Equals("127.0.0.1")) { cname = target.BloodHoundDisplay; } var dnsHostName = _utils.ResolveHost(cname); //If we're skipping Global Catalog deconfliction, just return a session if (_options.SkipGcDeconfliction) { yield return(new Session { ComputerName = dnsHostName, UserName = username, Weight = 2 }); } else { //Check our cache first if (!_cache.GetGcMap(username, out string[] possible) || possible == null)
/// <summary> /// Wraps the NetSessionEnum API call with a timeout and parses the /// </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)); 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('\\'); } //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 computerSid = computerSid ?? await Helpers.TryResolveHostToSid(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(sidSuccess, userSid) = await Helpers.AccountNameToSid(sessionUsername, computer.Domain, false); if (sidSuccess) { sessionList.Add(new Session { ComputerId = computerSid, UserId = userSid }); } else { sessionList.Add(new Session { ComputerId = computerSid, UserId = sessionUsername }); } } } return(sessionList); } finally { if (ptrInfo != IntPtr.Zero) { NetApiBufferFree(ptrInfo); } } }
List <SessionInfo> GetNetSessions(string server, string ComputerDomain) { List <SessionInfo> toReturn = new List <SessionInfo>(); IntPtr PtrInfo = IntPtr.Zero; int val; IntPtr ResumeHandle = IntPtr.Zero; Type si10 = typeof(SESSION_INFO_10); val = NetSessionEnum(server, null, null, 10, out PtrInfo, -1, out int EntriesRead, out int TotalRead, ref ResumeHandle); SESSION_INFO_10[] results = new SESSION_INFO_10[EntriesRead]; if (val == (int)NERR.NERR_Success) { IntPtr iter = PtrInfo; for (int i = 0; i < EntriesRead; i++) { results[i] = (SESSION_INFO_10)Marshal.PtrToStructure(iter, si10); iter = (IntPtr)(iter.ToInt64() + Marshal.SizeOf(si10)); } } NetApiBufferFree(PtrInfo); foreach (SESSION_INFO_10 x in results) { string username = x.sesi10_username; string cname = x.sesi10_cname; if (cname != null && cname.StartsWith("\\", StringComparison.CurrentCulture)) { cname = cname.TrimStart('\\'); } if (cname.Equals("[::1]")) { cname = server; } if (cname.Equals("127.0.0.1")) { cname = server; } if (username.EndsWith("$", StringComparison.CurrentCulture)) { continue; } if (username.Trim() == "" || username == "$" || username == CurrentUser) { continue; } if (!ResolveCache.TryGetValue(cname, out string DNSHostName)) { try { DNSHostName = Dns.GetHostEntry(cname).HostName; ResolveCache.TryAdd(cname, DNSHostName); } catch { DNSHostName = cname; } } GlobalCatalogMap obj; if (options.SkipGCDeconfliction) { obj = new GlobalCatalogMap { Username = username, PossibleNames = new List <string>() }; } else { if (!manager.GetGCMap(username, out obj)) { DirectorySearcher GCSearcher = helpers.GetDomainSearcher(ADSPath: GCPath); GCSearcher.Filter = $"(&(samAccountType=805306368)(samaccountname={username}))"; GCSearcher.PropertiesToLoad.AddRange(new string[] { "distinguishedname" }); List <string> possible = new List <string>(); foreach (SearchResult r in GCSearcher.FindAll()) { string dn = r.GetProp("distinguishedname"); string domain = Helpers.DomainFromDN(dn); possible.Add(domain.ToUpper()); } GCSearcher.Dispose(); obj = new GlobalCatalogMap { PossibleNames = possible, Username = username }; manager.InsertGCObject(obj); } } if (DNSHostName == null) { DNSHostName = cname; } if (obj.PossibleNames.Count == 0) { //We didn't find the object in the GC at all. Default to computer domain toReturn.Add(new SessionInfo { ComputerName = DNSHostName, UserName = $"{username}@{ComputerDomain}", Weight = 2 }); } else if (obj.PossibleNames.Count == 1) { //We found only one instance of the object toReturn.Add(new SessionInfo { ComputerName = DNSHostName, UserName = $"{username}@{obj.PossibleNames.First()}", Weight = 1 }); } else { //Multiple possibilities. Add each one with a weight of 1 for the same domain as the computer foreach (string p in obj.PossibleNames) { int weight; if (p.ToUpper().Equals(ComputerDomain.ToUpper())) { weight = 1; } else { weight = 2; } toReturn.Add(new SessionInfo { ComputerName = DNSHostName, UserName = $"{username}@{p}", Weight = weight }); } } } return(toReturn); }