2

Hey i am programming a RDP Bruteforce Protection program for a windows server i own, which even gets attacked after changing the RDP port :/

But i already suffer from logging in console, when there are 2 attacks at mostly same time, the console output "overlaps" like:

enter image description here

Minimalistic code to show what i do basically:

watcher.EventRecordWritten +=
                new EventHandler<EventRecordWrittenEventArgs>(EventLogEventRead);

public static async void EventLogEventRead(object obj,
        EventRecordWrittenEventArgs arg)
    {            
        if (arg.EventRecord != null)
        {
            string IP = GetIPFromRecord(arg.EventRecord)

            var json = await new HttpClient().GetStringAsync("https://api.ipgeolocationapi.com/geolocate/" + IP);
            var jsonDeserialized = new JavaScriptSerializer().Deserialize<dynamic>(json);
            string country = jsonDeserialized["name"];


            Console.WriteLine("IP:\t" + IP);
            Console.WriteLine("Country:\t" + country);
        }
        else
        {
            Console.WriteLine("The event instance was null.");
        }
    }

Full code (without Error Messages Class): Pastebin

So what is the most elegant way to solve such a problem?

iraj jelodari
  • 3,118
  • 3
  • 35
  • 45
Taki7o7
  • 197
  • 2
  • 11

2 Answers2

3

It overlaps because you have multiple calls of Console.WriteLine() for single log entry. You need to prepare whole output body and write it to console at once.

For example, change

Console.WriteLine("IP:\t" + IP);
Console.WriteLine("Country:\t" + country);

to

var msg = $"IP:\t{IP}{Environment.NewLine}Country:\t{country}";
Console.WriteLine(msg);

Or even better, use StringBuilder:

var builder = new StringBuilder();
builder.AppendLine($"IP:\t{IP}");
builder.AppendLine($"Country:\t{country}");
Console.WriteLine(builder.ToString());

Also I could recommend to use specialized logging framework, for example NLog (https://github.com/NLog/NLog). You will still need to write entries at once as described above, but it could help you with styling output and easily add other targets (files, network, etc) in future if required.

balbelias
  • 428
  • 5
  • 17
  • Hey thank you very much. Unfortunaly in my full code I use Console.Write to get the status message colored. So i think i can't prepare it this way. I should have shown that in the short code. Thanks for the NLog hint, gonna give it a try. – Taki7o7 Dec 25 '19 at 04:00
  • 1
    Well then you have to use locks as @Charles proposed in his answer. Or something lock-free if the speed is a concern for you. – balbelias Dec 25 '19 at 04:04
1

you should use a lock:

watcher.EventRecordWritten +=
                new EventHandler<EventRecordWrittenEventArgs>(EventLogEventRead);


private static readonly object myLock = new object();

public static async void EventLogEventRead(object obj, EventRecordWrittenEventArgs arg)
{          

    if (arg.EventRecord != null)
    {
        string IP = GetIPFromRecord(arg.EventRecord)

        var json = await new HttpClient().GetStringAsync("https://api.ipgeolocationapi.com/geolocate/" + IP);
        var jsonDeserialized = new JavaScriptSerializer().Deserialize<dynamic>(json);
        string country = jsonDeserialized["name"];

        lock (myLock) {
            Console.WriteLine("IP:\t" + IP);
            Console.WriteLine("Country:\t" + country);
        }
    }
    else
    {   
        lock (myLock) {
            Console.WriteLine("The event instance was null.");
        }
    }

}
Charles
  • 2,721
  • 1
  • 9
  • 15
  • Thank you very much. If i understand this right, if for example the ipgeolocation call takes longer for one log, so there are for example 3 logs one at second 41 one at 42 and one at 43, this will not ensure the correct sequence right? I found [this(dotnetfiddle)](https://dotnetfiddle.net/cM0Ccn) but i am not sure how to NOT only log the overlapping ones then – Taki7o7 Dec 25 '19 at 04:05
  • 1
    @Taki7o7 if you want to ensure the correct sequence 41,42,43 of EventLogs you can put the lock(mylock) around the whole EventLogEventRead function. The way i put it here will only make sure that the Console.WriteLine statements are always kept together. – Charles Dec 25 '19 at 04:35
  • Thank you very much, i don't even knew the lock function before. It seems to work fine now. – Taki7o7 Dec 25 '19 at 05:15