예제 #1
0
파일: Service.cs 프로젝트: unutmaz/rdpmon
        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");
        }
예제 #2
0
        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());
                }
            }
        }
예제 #3
0
        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!";
                }
            }
        }