Automatically Add Hackers to Firewall Block Rule

Discussion for developers using MailEnable.
SeanDevoy
Posts: 7
Joined: Wed Aug 03, 2011 11:16 am

Automatically Add Hackers to Firewall Block Rule

Post by SeanDevoy »

Hi,

I have found that MailEnables feature to fight brute force attacks by disabling the email account after X failed AUTHs does slow down the hackers, but really punishes the victims. If someone tries to hack into MY account and that rule fires, I am blocked from my own account. I think, but have not confirmed, that my own PC checking email every 5 minutes when the account is blocked keeps the account blocked.

I have written a short windows console application that I run in Task Scheduler every 5 minutes. It ignores all but the last 10 minutes of the log and counts AUTH failures (by source IP Address). When it gets to 6 (in 10 minutes) it adds that address to my Windows Firewall with Advanced Security INBOUND Rule that blocks all IPs in SCOPE on ports 25 and 587.

This is how FailToBan works on Unix systems, except it removes them from the block after X time. I say screw 'em, my customers some in on an alternate port any way!

Below is the code (you must add a ref to the c:\windows\system32\FireWallAPI.dll). You must also create the Firewall rule to block those ports and the Rule Name must match in the program exactly. Mine is called "Block EMAIL SMTP Hackers".

I could not upload ZIP file. Source is here: http://www.bizfocused.com/ME_FailToBan.zip

Main Console APP:

Code: Select all

Imports System.IO
Imports System.Text

Module Module1

    Sub Main()
        ' get the name of the lastest SMTP Activity log
        Dim filnam As String = "C:\Program Files (x86)\Mail Enable\Logging\SMTP\SMTP-Activity-" & Now.ToString("yyMMdd") & ".log"
        ' open the file shared as it is already open for write
        Dim s As New FileStream(filnam, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        Dim sr As New StreamReader(s)
        Dim line As String
        Dim fields() As String
        Dim logtime As Date
        Dim dict As New Dictionary(Of String, Integer)

        While Not sr.EndOfStream
            line = sr.ReadLine()
            ' split the line into fields on TABS
            fields = line.Split(vbTab)
            ' should get 12 fields
            If fields.GetUpperBound(0) >= 11 Then
                ' first field is date/time of this line
                logtime = Date.Parse(fields(0))
                ' only look in last 10 minutes
                If logtime.AddMinutes(10) > Now Then
                    ' we only care about AUTH records
                    If fields(5) = "AUTH" Then
                        ' we only care about auth failures
                        If fields(7) = "504 Invalid Username or Password" Then
                            ' fields(4) is IP address of remote host
                            ' do we have a count for this IP yet?
                            If dict.ContainsKey(fields(4)) Then
                                ' yes, add one too it
                                dict(fields(4)) += 1
                                ' is it 6 (or more not required)
                                If dict(fields(4)) = 6 Then
                                    ' add to firewall 
                                    BlockIP(fields(4))
                                    '                                    PrintLine("Blocking " & fields(4))
                                End If
                            Else
                                ' nope, create a count record with value 1
                                dict.Add(fields(4), 1)
                            End If
                        End If
                    End If
                End If
            End If
        End While
        sr.Close()
        sr.Dispose()
        s.Close()
        s.Dispose()

    End Sub

    Private Sub BlockIP(ByVal ipstr As String)
        'This needs to run with privs to modify firewall
        Dim fwall As New Firewall

        Dim ip_addr As System.Net.IPAddress = System.Net.IPAddress.Parse(ipstr)
        If Not fwall.Exists(ip_addr, "Block EMAIL SMTP Hackers") Then
            fwall.Add(ip_addr, "Block EMAIL SMTP Hackers")
        End If
        fwall.Dispose()
    End Sub
End Module
And the firewall Class:

Code: Select all

Imports NetFwTypeLib
Imports System.Net

Public Class Firewall
    Implements IDisposable

    Private _policy As INetFwPolicy2 = Nothing
    Private ReadOnly Property Policy As INetFwPolicy2
        Get
            If _policy Is Nothing Then
                _policy = DirectCast(Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2")), INetFwPolicy2)
            End If
            Return _policy
        End Get
    End Property

    Public Sub Add(ipAddress As IPAddress, ruleName As String)
        Dim firewallRule As NetFwTypeLib.INetFwRule = Policy.Rules.Item(ruleName)
        Dim NewAddress As String = ipAddress.ToString & "/255.255.255.255"
        If Not firewallRule.RemoteAddresses.Contains(NewAddress) Then
            firewallRule.RemoteAddresses += "," & NewAddress
        End If
    End Sub

    Public Sub Remove(ipAddress As IPAddress, ruleName As String)
        Dim firewallRule As NetFwTypeLib.INetFwRule = Policy.Rules.Item(ruleName)
        Dim NewAddress As String = ipAddress.ToString & "/255.255.255.255"
        If firewallRule.RemoteAddresses.Contains(NewAddress) Then
            Dim ipList As String = firewallRule.RemoteAddresses
            ipList = ipList.Replace(NewAddress, "")
            ipList = ipList.Replace(",,", ",")
            firewallRule.RemoteAddresses = ipList
        End If
    End Sub

    Public Function Exists(ipAddress As IPAddress, ruleName As String) As Boolean
        Dim firewallRule As NetFwTypeLib.INetFwRule = Policy.Rules.Item(ruleName)
        Dim NewAddress As String = ipAddress.ToString & "/255.255.255.255"
        If firewallRule.RemoteAddresses.Contains(NewAddress) Then
            Return True
        Else
            Return False
        End If
    End Function

    Private disposedValue As Boolean
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
            End If
            If Not _policy Is Nothing Then
                _policy = Nothing
            End If
        End If
        Me.disposedValue = True
    End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
End Class

Hope that helps someone else like it has me.

Sean

Ruffs
Posts: 25
Joined: Sun Jan 14, 2007 4:21 pm

Re: Automatically Add Hackers to Firewall Block Rule

Post by Ruffs »

Hi Sean,


Yes I was just asking about hooks into the MailEnable itself to allow us to process failed authentication attempts via the various connectors to action some work.

Whilst it's not ideal having to go through the logs like this, this is a good start for me to examine another approach to dealing with a similar request from a customer.

Thank you for posting this here, I appreciate it.


Kind regards,


Scott :)

Brett Rowbotham
Posts: 560
Joined: Mon Nov 03, 2003 7:48 am
Location: Cape Town

Re: Automatically Add Hackers to Firewall Block Rule

Post by Brett Rowbotham »

Just want to say thanks to Sean for posting his code.

I used the basic premise of the code to develop an EHLO ban mechanism (that I originally proposed in Suggestions) that adds the IP addresses of hackers, who constantly block user mail accounts through failed authentication attempts, to the SMTP deny list. Sean's approach gave me the code I needed to handle the parsing of the log files.

Thanks again.

Cheers,
Brett

Ruffs
Posts: 25
Joined: Sun Jan 14, 2007 4:21 pm

Re: Automatically Add Hackers to Firewall Block Rule

Post by Ruffs »

Hi Brett,


Was that to the Firewall, or MailEnable SMTP Block list?


Kind regards,


Scott :)

Brett Rowbotham
Posts: 560
Joined: Mon Nov 03, 2003 7:48 am
Location: Cape Town

Re: Automatically Add Hackers to Firewall Block Rule

Post by Brett Rowbotham »

I use the MailEnable SMTP block list (Config/SMTP-DENY.tab)

Cheers,
Brett

trusnock
Posts: 132
Joined: Tue Jan 31, 2006 8:42 pm

Re: Automatically Add Hackers to Firewall Block Rule

Post by trusnock »

I have been working through a similar solution but when I add a line to the SMTP-DENY.TAB file it seems to disappear (presumably ME is removing it) a few seconds to a minute later. Is there a trick to working with this file?

SeanDevoy
Posts: 7
Joined: Wed Aug 03, 2011 11:16 am

Re: Automatically Add Hackers to Firewall Block Rule

Post by SeanDevoy »

Hi All,

I have run into a problem since my original post. The Firewall rule limits entries in the SCOPE to 1024 (I think, it has been a while). I purged old entries, you could create another rule when you get too many entries but that would require some mechanism to "remember" what the latest rule name is and how many are in it.

Does the SMTP-DENY.TAB approach have a similar restriction?
Is there an API hook for adding entries to the SMTP-DENY list?

Sean

Brett Rowbotham
Posts: 560
Joined: Mon Nov 03, 2003 7:48 am
Location: Cape Town

Re: Automatically Add Hackers to Firewall Block Rule

Post by Brett Rowbotham »

The SMTP Administration COM object in MEAOSM.DLL has functions to read and write the SMTP-DENY.TAB file.

Cheers,
Brett

SeanDevoy
Posts: 7
Joined: Wed Aug 03, 2011 11:16 am

Re: Automatically Add Hackers to Firewall Block Rule

Post by SeanDevoy »

Thanks Brett.

SeanDevoy
Posts: 7
Joined: Wed Aug 03, 2011 11:16 am

Re: Automatically Add Hackers to Firewall Block Rule

Post by SeanDevoy »

HI,

I don't have ME on my development system so this is proving to be very difficult top test and debug.

Can you give me some sample code showing how to use the COM Object to add the DENY list item?

Also, if there is a way to use Remote Administration to develop on a non-ME machine, I would love some tips on how to get started. Do I have to install the free version locally?

Thanks,
Sean

Brett Rowbotham
Posts: 560
Joined: Mon Nov 03, 2003 7:48 am
Location: Cape Town

Re: Automatically Add Hackers to Firewall Block Rule

Post by Brett Rowbotham »

The only code I have is in VB.Net. I was using an Interop based on the typelib of MEASOM.dll but have now changed over to use MailEnable.Administration.dll. In either case the code is the same so you should be able to work it out from there.

Code: Select all

	Private Sub BlockIP(ByVal ipstr As String)
		Dim smtpAccess As New Administration.SMTPAccess()
		Dim res As Integer, add As Boolean = True

		Try
			With smtpAccess
				' Set filter defaults
				.AddressMask = ""
				.Host = ""
				.Mode = 1
				.Account = ""
				.Right = ""
				.Status = -1

				res = .FindFirstAccess()
				Do While res > 0
					If .AddressMask = ipstr Then
						add = False
						Exit Do
					End If
					' Reset filter defaults
					.AddressMask = ""
					.Host = ""
					.Mode = 1
					.Account = ""
					.Right = ""
					.Status = -1
					res = .FindNextAccess()
				Loop
				If add = False Then
					'Console.WriteLine(ipstr & " is already in deny list")
					Exit Sub
				End If
				.AddressMask = ipstr
				.Host = ""
				.Mode = 1
				.Account = "SYSTEM"
				.Right = "CONNECT"
				.Status = 1
				res = .AddAccess()
				'Console.WriteLine("Add result = " & CStr(res))
				logger.Info("Ban IP " & ipstr & " with result code " & CStr(res))
			End With

		Catch ex As Exception
			'Console.WriteLine("Exception: " & ex.Message)
			logger.Error("BlockIP Exception", ex)
			EmailException(ex.Message)
		End Try
	End Sub

twun
Posts: 24
Joined: Tue Dec 16, 2014 6:42 pm

Re: Automatically Add Hackers to Firewall Block Rule

Post by twun »

Thanks for this Sean,

I have implemented this on my server in a hope to stop my accounts getting hacked.

I had to update the code a bit as I am based in the UK, and it was not liking the parsing of the date times.

Code: Select all

Imports System.IO
Imports System.Text
Imports System.Globalization

Module Module1

    Sub Main()
        ' get the name of the lastest SMTP Activity log
        Dim filnam As String = "C:\Program Files (x86)\Mail Enable\Logging\SMTP\SMTP-Activity-" & Now.ToString("yyMMdd") & ".log"
        ' open the file shared as it is already open for write
        Dim s As New FileStream(filnam, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
        Dim sr As New StreamReader(s)
        Dim line As String
        Dim fields() As String
        Dim logtime As DateTime
        Dim dict As New Dictionary(Of String, Integer)

        While Not sr.EndOfStream
            line = sr.ReadLine()
            ' split the line into fields on TABS
            fields = line.Split(vbTab)
            ' should get 12 fields
            If fields.GetUpperBound(0) >= 11 Then
                ' first field is date/time of this line
                logtime = DateTime.Parse(fields(0), System.Globalization.CultureInfo.GetCultureInfo("en-us"))
                ' only look in last 10 minutes
                If logtime.AddMinutes(10) > DateTime.Now Then
                    ' we only care about AUTH records
                    If fields(5) = "AUTH" Then
                        ' we only care about auth failures
                        If fields(7) = "504 Invalid Username or Password" Then
                            ' fields(4) is IP address of remote host
                            ' do we have a count for this IP yet?
                            If dict.ContainsKey(fields(4)) Then
                                ' yes, add one too it
                                dict(fields(4)) += 1
                                ' is it 6 (or more not required)
                                If dict(fields(4)) = 6 Then
                                    ' add to firewall 
                                    BlockIP(fields(4))
                                    '                                    PrintLine("Blocking " & fields(4))
                                End If
                            Else
                                ' nope, create a count record with value 1
                                dict.Add(fields(4), 1)
                            End If
                        End If
                    End If
                End If
            End If
        End While
        sr.Close()
        sr.Dispose()
        s.Close()
        s.Dispose()

    End Sub

luket
Posts: 7
Joined: Sun Jan 31, 2016 8:09 pm

Re: Automatically Add Hackers to ME Access Control List

Post by luket »

Hi all,

I too have decided to tackle this problem and have what I believe to be a good solution.
First off though, we all have slightly different requirements, so I will first explain what my program does, then I will highlight those areas where you may want to make modifications.

I'd like to thank Sean for the original concept and Brett for pointing me at the MailEnable.Administration.dll.

Okay, here we go;
1. I read the activity log file like we have been taking about. I get the location from the official registry key defined by MailEnable (no hard-coding.)

2. I loop forever with a Sleep(). I chose this because sleeping is is less expensive CPU wise than a fresh program launch via scheduler.
Also, sleeping allows us to do most of our setup one-time only.

3. With each activity file roll-over (each midnight) I clear the ME Access Control (ban) list and start anew.
** your requirements may differ **
This works for me since it makes the code clear and straight forward. No need to attach an expiration date to each IP address, yuck. Simply clear the list every night and start over. So what if bad-guyX gets one more failed login attempt before being banned again?

4. Once lines are processed, I do not process them again and instead zip through the file to the last read entry in the file.
I still 'read' the lines, but throw them away immediately without ever doing any parsing or matching. This is very fast and has almost no cost (I am testing this on 20K to 40K line files.)
** optimization **
You probably could use Seek() to eliminate the reading the lines altogether, but I found my method clear and fast enough.

5. My program bans on the FIRST failed login.
** your requirements will be different **
My situation is somewhat special in that I do not have user-owned mail boxes. All mailboxes are owned by me.
I do send email to my subscribers, and my subscribers send me email, but I don't have random users logging into my mailboxes. Therefore I *know* any failed login is an attack and therefore block it.
==> You can easily modify my implementation to count failed login attempts and ban accordingly.

6. This is a console app that displays the various state changes: banning someone, clearing the ban list, etc.
You can easily launch this app on machine startup or user login from a login script.

I think that's about it.

Best to all,
luket

[UPDATE] Version 2

This version adds the following enhancements:

1. Only reads the log file if there has been an update.
(This works hand-in-hand with only reading those lines that are new.)

2. Special midnight log rollover check handling.
I suspect a race condition where we are trying to open/read the new file and ME either hasn't created it yet, or is in the process of creating/writing it. This code now ensures we are out of the way when ME goes to create the file and write to it for the first time.
I left the diagnostic message in place as they describe the interesting midnight rollover sequence.

3. Partial line handling.
It is possible to read a partial line because ME has not finished writing it. This code detects such an edge case and ignores such lines and ensures it is read next pass.

Code: Select all

#undef LOCAL   // define LOCAL to use local copy of ME activity for debugging / development

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;

namespace BanFailLogin
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = AppDomain.CurrentDomain.BaseDirectory;
            path = path.Replace("\\", "/");         // cleanup the path
            Directory.SetCurrentDirectory(path);    // set current directory to the path of this executable
            DateTime lastDateTime = new DateTime(); // place to save the date
            string activityFile = string.Empty;     // file to parse
            int last_lineRead = 0;                  // last line read
            int current_lineRead = 0;               // current line
            List<String> ips = new List<String>();  // Create a list of IP addresses.
            long last_fileLength = 0;               // we check this to see if the file has been written to

#if (LOCAL)
            // just use the current path (".") to an activiy file for debug / development purposes
            // the current path will point to a local copy of the avtivity file that lives with this exe            
#else
            // read the location of the real activity log file
            String keyName = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Mail Enable\\Mail Enable\\Connectors\\SMTP\\";
            path = (string)Microsoft.Win32.Registry.GetValue(keyName, "Activity Log Directory", path);
            path = path.Replace("\\", "/");                 // cleanup the path
            if (path[path.Length - 1] != '/') path += '/';  // add a trailing '/' if needed
#endif

            // first time run
            if (activityFile == String.Empty)
            {
                // create the name of the new activity file
                activityFile = String.Format("{0}SMTP-Activity-{1}.log", path, DateTime.Now.ToString("yyMMdd"));
                lastDateTime = DateTime.Now;    // a new day and a fresh start
                last_lineRead = 0;              // start over at the beginning of the file
                last_fileLength = 0;            // don't read the file unless the file size changes`                               
            }

            // forever baby
            for (; ; )
            {
                // MIDNIGHT ROLLOVER CODE
                // if we have rolled over to a new day AND ME has created a new activity file, reset everything:
                //  get the new file name, clear the ME ban list, clear our local copy of banned addresses,
                //  reset the last_lineRead so that we start reading at the beginning of the new file
                // But don't wait until we have actually rolled over since it can cause a race condition between us trying to 
                //  read the old file while ME is trying to delete it. Instead enter our waiting state 5 seconds before 
                //  midnight to make sure we  are well out of the way when ME deletes the old file and creates the new file.
                int secondsToMidnight = 0;
                if (lastDateTime.Day == DateTime.Now.Day)
                {   // this if statement protects us incase the clock has already rolled over and we missed it.
                    //  in this case, we just proceed as if it's midnight.
                    TimeSpan ts = DateTime.Today.AddDays(1).Subtract(DateTime.Now);
                    secondsToMidnight = (int)ts.TotalSeconds;
                }
                if (secondsToMidnight <= 5)
                {
                    try
                    {
                        // *** DIAG
                        // we found that ME didn't delete the old activity file until 175 minutes after midnight.
                        //  This probably means that the creation of the new one (which is created at precisely at midnight) 
                        //  and the deletion of the old one are not bound, but rather the delition of the old one is done in some
                        //  lazy cleanup task. We will try to prove that now.
                        String old_activityFile = activityFile;
                        // *** DIAG

                        Console.WriteLine("It's {0} seconds until midnight, entering a waiting state.", secondsToMidnight);

                        // Wait for the day to click over to a new day
                        //  will just loop until it's ready.
                        while (lastDateTime.Day == DateTime.Now.Day)
                        {
                            Console.WriteLine("Waiting for midnight...");
                            System.Threading.Thread.Sleep(5000);                        // give ME a chance to update without us having it open
                            continue;                                                   // just loop without doing any more work.
                        }
                        Console.WriteLine("Okay, it's midnight...");

                        // create/get the name of the new activity file
                        activityFile = String.Format("{0}SMTP-Activity-{1}.log", path, DateTime.Now.ToString("yyMMdd"));

                        // Okay, now wait for the new activity file
                        //  will just loop until it's ready.
                        while (File.Exists(activityFile) == false)
                        {   // it's midnight but ME has not yet created the new log file
                            Console.WriteLine("Waiting for ME to create the new Activity file...");
                            System.Threading.Thread.Sleep(5000);                        // give ME a chance to update without us having it open
                            continue;                                                   // just loop without doing any more work.
                        }
                        Console.WriteLine("Okay, new Activity file created at {0}.", DateTime.Now);

                        if (File.Exists(old_activityFile))
                            Console.WriteLine("Old Activity file still exists at {0} and is {1} bytes.", DateTime.Now, new FileInfo(old_activityFile).Length);
                        else
                            Console.WriteLine("Old Activity file no longer exists at {0}.", DateTime.Now);

                        // Okay, now wait for the new activity file to contain some data
                        //  will just loop until it's ready.
                        while (new FileInfo(activityFile).Length == 0)
                        {   // ME has created the new log file, but it is empty
                            Console.WriteLine("Waiting for ME to write to the new Activity file...");
                            if (File.Exists(old_activityFile))
                                Console.WriteLine("Meanwhile, the old Activity file exists and is {0} bytes", new FileInfo(old_activityFile).Length);
                            System.Threading.Thread.Sleep(5000);                        // give ME a chance to update without us having it open
                            continue;                                                   // just loop without doing any more work.
                        }
                        Console.WriteLine("Okay, the new Activity file contains data at {0}.", DateTime.Now);

                        // *** DIAG
                        if (File.Exists(old_activityFile))
                        {// it's midnight but ME has not yet deleted the old log file
                            Console.WriteLine("At {0}:", DateTime.Now);
                            Console.WriteLine("The new activity file exists and has been written to, but the old Activity file still exists.");
                            Console.WriteLine("The old Activity file is {0} bytes", new FileInfo(old_activityFile).Length);
                            Console.WriteLine("We will just continue on now and assume ME will clean this up later");
                        }
                        // *** DIAG

                        // okay, the new activity file has been created by ME
                        Console.WriteLine(String.Format("** Resetting: banned IP Addresses **"));
                        TimeSpan tx = DateTime.Now - new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);
                        Console.WriteLine("** Reset at " + tx.TotalMinutes.ToString() + " minutes past midnight");
                        lastDateTime = DateTime.Now;                                // a new day and a fresh start
                        ClearMEBanList();                                           // Clear the ME ban list
                        ips.Clear();                                                // Clear our local ban list
                        last_lineRead = 0;                                          // start over at the beginning of the file
                        last_fileLength = 0;                                        // initial value
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex);
                    }
                }
                try
                {   // only process if the file has changed size
                    if (new FileInfo(activityFile).Length != last_fileLength)
                    {
                        last_fileLength = new FileInfo(activityFile).Length;

                        // Open the text file using a stream reader.
                        using (FileStream fs = new FileStream(activityFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        {
                            using (StreamReader sr = new StreamReader(fs))
                            {
                                String line;
                                current_lineRead = 0;

                                // skip over the parts we have already read
                                while ((line = ReadLine(sr)) != null)
                                {

                                    // skip over lines we have already read
                                    if (current_lineRead < last_lineRead)
                                    {
                                        current_lineRead++;
                                        continue;
                                    }
                                    // there are new lines to read, lets read them now
                                    break;
                                }

                                // check and see if we are at the end of the file
                                if (line != null)
                                {
                                    // Read a line and split into fields
                                    do
                                    {   // we read another line
                                        last_lineRead++;

                                        // see if it's an invalid login (hacker)
                                        if (line.IndexOf("535 Invalid Username or Password") != -1)
                                        {
                                            string[] fields = line.Split();
                                            if (fields.Length >= 6)
                                            {   // record the IP address
                                                if (ips.Contains(fields[5]) == false)
                                                {
                                                    ips.Add(fields[5]);
                                                    AddMEBanList(fields[5]);                                           // Add to the ME ban list
                                                    Console.WriteLine("Banning IP Address: " + fields[5]);
                                                }
                                            }
                                        }
                                    } while ((line = ReadLine(sr)) != null);
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("The file could not be read:");
                    Console.WriteLine(e.Message);
                }

                // always sleep
                System.Threading.Thread.Sleep(5000);
            }
        }

        static void ClearMEBanList()
        {
            MailEnable.Administration.SMTPAccess smtpAccess = new MailEnable.Administration.SMTPAccess();

            // Set filter defaults
            smtpAccess.AddressMask = "";
            smtpAccess.Host = "";
            smtpAccess.Mode = 1;
            smtpAccess.Account = "";
            smtpAccess.Right = "";
            smtpAccess.Status = -1;

            int res = smtpAccess.FindFirstAccess();
            while (res > 0)
            {   // wipe this guy from the naughty list
                Console.WriteLine("Wiping " + smtpAccess.AddressMask + " from ME ban list");
                smtpAccess.RemoveAccess();
                // reset filter defaults
                smtpAccess.AddressMask = "";
                smtpAccess.Host = "";
                smtpAccess.Mode = 1;
                smtpAccess.Account = "";
                smtpAccess.Right = "";
                smtpAccess.Status = -1;
                //res = smtpAccess.FindNextAccess();    // list gets messed up when calling Next 
                res = smtpAccess.FindFirstAccess();     //  and deleting. Better to keep calling First
            }

        }

        static void AddMEBanList(String ips)
        {
            MailEnable.Administration.SMTPAccess smtpAccess = new MailEnable.Administration.SMTPAccess();

            // Set filter to add
            smtpAccess.AddressMask = ips;
            smtpAccess.Host = "";
            smtpAccess.Mode = 1;
            smtpAccess.Account = "SYSTEM";
            smtpAccess.Right = "CONNECT";
            smtpAccess.Status = 1;

            // ban this guy
            smtpAccess.AddAccess();
        }

        static String ReadLine(StreamReader sr)
        {
            try
            {
                // read a line of text
                //  we write our own line-reader here so that we can know if the line is complete, ending in \r\n
                //  if the line is not terminated properly, we may be reading before ME has finished writing.
                //  in such a case, we will ignore the line and read it again next time.
                String line = null;
                int cx;
                bool have_term = false;
                while ((cx = sr.Read()) != -1)
                {
                    switch (cx)
                    {
                        case '\r': continue;
                        case '\n': { have_term = true; break; }
                        default: { line += (Char)cx; continue; }
                    }
                    break;
                }

                /////////////////////////
                // The next two checks make sure the line is properly terminated. 
                //  we check both cases since we don't know what happens if you are reading
                //  while the other process is writing. Will you read EOF? Better to be safe.

                // have we reached EOF?
                if (cx == -1)
                {   // we should never reach EOF with a valid line
                    line = null;
                    return null;
                }

                // see if our line is properly terminated 
                if (have_term == false)
                {   //  if not, we will ignore this line and read it next time
                    line = null;
                    return null;
                }

                return line;
            }
            catch
            {
                return null;
            }
        }
    }
}

virmix
Posts: 66
Joined: Tue Nov 10, 2015 12:12 am

Re: Automatically Add Hackers to Firewall Block Rule

Post by virmix »

I create a new service using this code as base.

:arrow: http://forum.mailenable.com/download/file.php?id=301 (Update: 05.12.16)

The fist code/service check :

- wrong username or password

The new service check more items :

- null username or email account
- invalid auth or username
- log languaje (en/es)
- refresh settings without restart service
- Set interval check


I test it now and work.
Remember set priv to exe for firewall
Last edited by virmix on Mon Dec 05, 2016 12:21 pm, edited 3 times in total.

tmartins
Posts: 2
Joined: Tue Nov 01, 2016 9:24 am

Re: Automatically Add Hackers to Firewall Block Rule

Post by tmartins »

Hello, file is not available any more. Can you post another link?
Thanks

Post Reply