void MainThread() { var logprefix = "MainThread: "; var upsince = DateTime.UtcNow; var iteration = 0; var myExeName = System.IO.Path.GetFileNameWithoutExtension(Utils.MyExe()); var myPid = System.Diagnostics.Process.GetCurrentProcess().Id; var connectionsAggregator = new ConnectMon(true, true); while (!Stopping) { try { Log(logprefix + "iteration #" + (++iteration)); connectionsAggregator.Aggregate(DateTime.MinValue); } catch (Exception ex) { Log(logprefix + "* exception: " + ex.ToString()); } var myProcesses = System.Diagnostics.Process.GetProcessesByName(myExeName); var guiProcesses = from n in myProcesses where n.Id != myPid select n; int wait; if (guiProcesses.Any()) { Log(logprefix + "GUI boost mode"); wait = 10 * 1000; } else { wait = 3 * 60 * 1000; // CPU saving mode } waitEvent.WaitOne(wait); } Log(logprefix + "quitting"); }
static void Main(string[] args) { if (args.Length >= 1 && args[0].Equals("-dbgnow", StringComparison.InvariantCultureIgnoreCase)) { return; } else if (args.Length >= 1 && args[0].Equals("-shadownoconsent", StringComparison.InvariantCultureIgnoreCase)) { // ShadowNoConsent Log("ShadowNoConsent: in"); var ret = Utils.RegWriteDword(Microsoft.Win32.Registry.LocalMachine, @"SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services", "Shadow", 4); Log("ShadowNoConsent: out, ret=" + ret); return; } else if (args.Length >= 1 && args[0].Equals("-inst", StringComparison.InvariantCultureIgnoreCase)) { // Installer Log("Inst: in"); try { // Pre-install uninst int exitCode = -1; Utils.ExecProg(Utils.MyExe(), "-uninst", ref exitCode, 45 * 1000, false); System.Configuration.Install.ManagedInstallerClass.InstallHelper(new[] { Utils.MyExe() }); Utils.StartService("RdpMon"); } catch (Exception ex) { Log("* Exception: " + ex.GetType().Name + ", " + ex.InnerException.GetType().Name); } Log("Inst: out"); } else if (args.Length >= 1 && args[0].Equals("-uninst", StringComparison.InvariantCultureIgnoreCase)) { // Uninstaller Log("Uninst: in"); try { Utils.StopService("RdpMon"); Thread.Sleep(1000); System.Configuration.Install.ManagedInstallerClass.InstallHelper(new[] { "/u", Utils.MyExe() }); Thread.Sleep(1000); } catch (Exception ex) { Log("* Exception: " + ex.GetType().Name + ", " + ex.InnerException.GetType().Name); } Log("Uninst: out"); } else if (args.Length >= 1 && args[0].Equals("-collect", StringComparison.InvariantCultureIgnoreCase)) { // Explicit aggregation, called by GUI in portable mode var aggregator = new ConnectMon(true, true); var _addrs = aggregator.Aggregate(DateTime.MinValue); } else { // Service engine var isSystem = Utils.IsSystemUser(); Globals.IsSystem = isSystem; Log("Main: user="******" [SYSTEM]" : "")); if (isSystem) { ServiceBase[] services = { new RdpMon.Service() }; ServiceBase.Run(services); } else { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // Check if already installed as a service var installed = (IsSvcInstalled("RdpMon", Utils.MyExe(), out var started)); if (!installed) { var resp = MessageBox.Show(null, "RdpMon will now install as a service and start collecting data.\n" + "You can uninstall this service using the command: 'rdpmon.exe -uninst'", Utils.MyExe(), MessageBoxButtons.OKCancel); if (resp == DialogResult.Cancel) { Application.Exit(); return; } var elevate = !Utils.IsElevated(); int exitCode = -1; var ok = Utils.ExecProg(Utils.MyExe(), "-inst", ref exitCode, 45 * 1000, elevate); if (ok && exitCode == 0) { exitCode = -1; Utils.ExecProg(Utils.MyExe(), null, ref exitCode, 45 * 1000, false); } else { MessageBox.Show("Failed installing service. Please try again."); } Application.Exit(); return; } // Check if service is started if (!started) { MessageBox.Show("Warning: 'RdpMon' service is not started. Data cannot be collected."); } // Start GUI var mutexName = "RdpMon.GUI"; var mutex = new Mutex(true, mutexName); if (!mutex.WaitOne(0)) { MessageBox.Show("Application is already running, quitting."); return; } try { var evt = EventWaitHandle.OpenExisting(@"Global\RdpMonRefresh"); evt.Set(); } catch (Exception ex) { Log("Could not open global event (benign): " + ex.Message); } Application.Run(new MainForm()); } } }
void RefreshConnectionsLV(bool initialLoad) { int exitCode = 0; var startedLvUpdate = false; var lv = connectsLv; // Initial load or update? if (initialLoad) { lastConnectRefresh = DateTime.MinValue; startedLvUpdate = true; lv.BeginUpdate(); lv.ListViewItemSorter = null; lv.Items.Clear(); totalAttackers = totalAttempts = totalLegits = 0; } var now = DateTime.UtcNow; if (dbg) { Utils.ExecProg(Utils.MyExe(), "-collect", ref exitCode, 60000, false); } var _from = (lastConnectRefresh < fromDate ? fromDate : lastConnectRefresh); // Aggregate logins var aggregator = new ConnectMon(/*fromDate*/ false, false); var _addrs = aggregator.Aggregate(_from); var changes = _addrs.Items.Count; addrs = _addrs; foreach (var item in addrs.Items) { var ip = item.Key; var addr = item.Value; var isAttack = addr.IsAttack(); var isLegit = addr.IsLegit(); //var isAttack = (addr.SuccessCount == 0); //if (isAttack && !addr.IsAttack()) // continue; if (addr.Last < lastConnectRefresh) { continue; } // Filter if (isAttack && !filterBtnAttacks.Checked) { continue; } if (isLegit && !filterBtnLegits.Checked) { continue; } if (!isAttack && !isLegit && !filterBtnUnknown.Checked) { continue; } if (!startedLvUpdate) { startedLvUpdate = true; lv.BeginUpdate(); lv.ListViewItemSorter = null; } var existingidx = -1; for (int i = 0; i < lv.Items.Count; i++) { if (lv.Items[i].Text == ip) { existingidx = i; break; } } ListViewItem lvi; if (existingidx != -1) { lvi = lv.Items[existingidx]; } else { lvi = new ListViewItem(); lvi.SubItems.AddRange(new[] { "", "", "", "", "", "" }); } lvi.SubItems[colIP.DisplayIndex].Text = ip; lvi.SubItems[colFailCount.DisplayIndex].Text = addr.FailCount.ToString(); lvi.SubItems[colSuccessCount.DisplayIndex].Text = addr.SuccessCount.ToString(); lvi.SubItems[colFirstTime.DisplayIndex].Text = addr.First.ToLocalTime().ToString("MM/dd HH:mm:ss"); lvi.SubItems[colLastTime.DisplayIndex].Text = addr.Last.ToLocalTime().ToString("MM/dd HH:mm:ss"); if (addr.UserNames.Count() <= 5) { lvi.SubItems[colLogins.DisplayIndex].Text = string.Join(", ", addr.UserNames); } else { lvi.SubItems[colLogins.DisplayIndex].Text = string.Join(", ", addr.UserNames.Take(5)) + $"... ({addr.UserNames.Count})"; } if (isAttack) { lvi.ImageIndex = 0; if (addr.IsOngoing()) //|| (lastRefresh != DateTime.MinValue && attack.Last > lastRefresh)) { lvi.SubItems[colDuration.DisplayIndex].Text = "ongoing"; lvi.UseItemStyleForSubItems = false; lvi.SubItems[colDuration.DisplayIndex].ForeColor = Color.Red; //lvi.ImageIndex = 1; } else { lvi.SubItems[colDuration.DisplayIndex].Text = Utils.DurationStr(addr.Last.Subtract(addr.First)); } } else if (isLegit) { lvi.ImageIndex = 1; } else // Neither attack nor legit; not enough data { lvi.ImageIndex = 2; } lvi.Tag = addr; if (existingidx == -1) { lv.Items.Add(lvi); if (isAttack) { totalAttackers++; } else if (isLegit) { totalLegits++; } } } if (!initialLoad) { totalAttempts = 0; for (int i = 0; i < lv.Items.Count; i++) { // Update "Ongoing" items that are no longer ongoing if (lv.Items[i].SubItems[colDuration.DisplayIndex].Text == "ongoing") { var _addr = (Addr)lv.Items[i].Tag; if (!_addr.IsOngoing()) { lv.Items[i].SubItems[colDuration.DisplayIndex].Text = Utils.DurationStr(_addr.Last.Subtract(_addr.First)); lv.Items[i].UseItemStyleForSubItems = true; lv.Items[i].ForeColor = Color.Black; //lv.Items[i].ImageIndex = 0; } } var addr = (Addr)lv.Items[i].Tag; totalAttempts += addr.FailCount; } } if (startedLvUpdate) { lv.ListViewItemSorter = connectsSorter; lv.Sort(); lv.EndUpdate(); lv.ListViewItemSorter = null; } lastConnectRefresh = now; // Statistics toolStripStatsLabel.Text = totalLegits + " legitimate users, " + totalAttackers + " suspected addresses"; if (totalAttempts > 0) { toolStripStatsLabel.Text += ", " + totalAttempts + " password attempts"; if (nla <= 0) { toolStripStatsLabel.Text += ", WARNING: NLA not activated on this machine!"; } } }