How Do I Block All Mail Containing a Specific String

Use this forum if you have installed hMailServer and want to ask a question related to a production release of hMailServer. Before posting, please read the troubleshooting guide. A large part of all reported issues are already described in detail here.
Post Reply
User avatar
CopBlaster
New user
New user
Posts: 23
Joined: 2019-06-28 11:17
Location: Portland, Oregon
Contact:

How Do I Block All Mail Containing a Specific String

Post by CopBlaster » 2019-09-27 23:57

I keep getting a lot of spam containing old passwords and threats to disseminate them if I do not pay the ransom. Is there any way to keep hMailServer from accepting any messages with those passwords?

I am new to hMailServer and have never written rules for it before. I would like something that says if email contains specific string then block.

User avatar
mattg
Moderator
Moderator
Posts: 20900
Joined: 2007-06-14 05:12
Location: 'The Outback' Australia

Re: How Do I Block All Mail Containing a Specific String

Post by mattg » 2019-09-28 03:59

rules don't block senders

Rules CAN delete messages

Global rule

If BODY contains Specifc_String
THEN
Delete message
Just 'cause I link to a page and say little else doesn't mean I am not being nice.
https://www.hmailserver.com/documentation

Kendo
Normal user
Normal user
Posts: 100
Joined: 2015-07-08 23:33
Location: Rural Australia

Re: How Do I Block All Mail Containing a Specific String

Post by Kendo » 2019-09-30 03:22

I am currently working on a new filter to detect keywords and delete if found. It is based on the bad word filter mentioned earlier but instead of replacing the word, I intend to delete it.

The words are contained in a text file and will have a score and when total threshold reaches the set limit, then the email is deleted.

I'll keep you posted.

Kendo
Normal user
Normal user
Posts: 100
Joined: 2015-07-08 23:33
Location: Rural Australia

Re: How Do I Block All Mail Containing a Specific String

Post by Kendo » 2019-10-05 04:24

Kendo wrote:
2019-09-30 03:22
I am currently working on a new filter to detect keywords and delete if found.
We have completed this but need to debug. Is it cool to add a report to the logfile, such as wordscore?

If so, then what format/procedure should be observed?

palinka
Senior user
Senior user
Posts: 1968
Joined: 2017-09-12 17:57

Re: How Do I Block All Mail Containing a Specific String

Post by palinka » 2019-10-05 04:50

Use the event log.

Code: Select all

EventLog.Write( "whatever you want to record." )

Kendo
Normal user
Normal user
Posts: 100
Joined: 2015-07-08 23:33
Location: Rural Australia

Re: How Do I Block All Mail Containing a Specific String

Post by Kendo » 2019-10-10 10:33

Ok, my blocklist filter is finished and it works.

How it works

block-list.txt contains a list of word and phrases that you want to block (create your own). In the script you can set a threshold of say 50 which when reached will delete the email so that it is not delivered.

In block-list.txt you need to enter each word/phrase per line with a score, for example:

dick, 20
meet women, 30
pharma, 30
sex, 30

You can set words at 50 or lower so that a second instance or another word can trigger the threshold, it's up to you.

Code: Select all

Sub OnDeliverMessage(oMessage)
	
	'Commence block-list filter

	Dim strWords
	Dim i
	Dim strBadWord
	Dim blnReject
	Dim dicWordCount
	Dim dicWordScore
	Dim intBadWordCount : intBadWordCount = 0
	Dim intBadScore
	Dim strLine

	Const THRESHOLD = 50
	Dim Location : Location = "C:\Program Files (x86)\hMailServer\block-list.txt"
	 
	Dim strBody : strBody = LCase(oMessage.Body)
	Dim strHTMLBody : strHTMLBody = LCase(oMessage.HTMLBody)
	Dim strSubject : strSubject = LCase(oMessage.Subject)

	Set dicWordCount = CreateObject("Scripting.Dictionary")
	Set dicWordScore = CreateObject("Scripting.Dictionary")

	Set objFSO = CreateObject("Scripting.FileSystemObject")
	Set objTextFile = objFSO.OpenTextFile(Location, 1)

	Do While objTextFile.AtEndOfStream <> True
	strLine = objTextFile.Readline

	If Len(strLine) >=2 And InStr(strLine,",") >=1 Then
	arrWords = Split(strLine, ",")
	strBadWord = Trim(arrWords(0))
	intBadScore =  Int(Trim(arrWords(1)))

	If InStr(strSubject,strBadWord) >=1 Then
	intBadWords = Int(UBound(Split(strSubject,strBadWord))) * intBadScore

	If dicWordCount.Exists(strBadWord) = False Then
	   dicWordCount.Add strBadWord,intBadWords
	End If
	End If

	If InStr(strBody,strBadWord) >=1 Then
	intBadWords = Int(UBound(Split(strBody,strBadWord))) * intBadScore

	If dicWordCount.Exists(strBadWord) = False Then
	   dicWordCount.Add strBadWord,intBadWords
	Else
	   dicWordCount.Item(strBadWord) = Int(dicWordCount.Item(strBadWord)) + intBadWords
	End If
	End If
	End If
	Loop

	objTextFile.Close()

	arrBadWordCount = dicWordCount.Items
		   
	For i = 0 To UBound(arrBadWordCount)
	intBadWordCount = Int(arrBadWordCount(i)) + intBadWordCount
	Next

	If intBadWordCount >= THRESHOLD Then
	oMessage.HeaderValue("X-hMailServer-Mime-Ban") = "YES"
	Result.Value = 1
	EventLog.Write( "not delivered" )
	Else
	Result.Value = 0
	EventLog.Write( "delivered" )
	End If
	  
End Sub

When satisfied that it works for you, comment out the lines "EventLog.Write..." to stop logging to hmailserver_events.log

Kendo
Normal user
Normal user
Posts: 100
Joined: 2015-07-08 23:33
Location: Rural Australia

Re: How Do I Block All Mail Containing a Specific String

Post by Kendo » 2019-10-19 08:06

Further to my block-list filter I found that was still getting some spam emails even though they should have been blocked.

So we added more informative logging and then discovered that the emails that were getting through were excused because the message body was encoded.

I was thinking of decoding and then checking for bad words, but a suggestion has been made... if encoding is found should we simply delete the email?

So my question is, if Content-Transfer-Encoding: base64 is found can we safely assume that it is spam, otherwise why would anyone use base64 encoding in email?

User avatar
jimimaseye
Moderator
Moderator
Posts: 8647
Joined: 2011-09-08 17:48

Re: How Do I Block All Mail Containing a Specific String

Post by jimimaseye » 2019-10-19 10:50

I think all mail composed by Outlook (online or maul client) is encoded (legit or otherwise).

[Entered by mobile. Excuse my spelling.]
5.7 on test.
SpamassassinForWindows 3.4.0 spamd service
AV: Clamwin + Clamd service + sanesecurity defs : https://www.hmailserver.com/forum/viewtopic.php?f=21&t=26829

1Icarus2
New user
New user
Posts: 3
Joined: 2020-01-03 18:20

Re: How Do I Block All Mail Containing a Specific String

Post by 1Icarus2 » 2020-01-03 18:23

Did you ever manage to enhance your script to decode emails? I am too having the same issue where your script works perfectly for plain emails, but encoded emails fails. :(

1Icarus2
New user
New user
Posts: 3
Joined: 2020-01-03 18:20

Re: How Do I Block All Mail Containing a Specific String

Post by 1Icarus2 » 2020-01-03 18:24

Also, can I ask for a request, can you enhance the script to also check the subject for the banned words. This way, an encoded message can still be processed by the script without having to decode it.

Kendo
Normal user
Normal user
Posts: 100
Joined: 2015-07-08 23:33
Location: Rural Australia

Re: How Do I Block All Mail Containing a Specific String

Post by Kendo » 2020-01-03 23:10

Decoding didn't work for us. Perhaps someone else can fix that part.

Yes, we are checking both Subject and Message.

Code: Select all

'   Sub OnClientConnect(oClient)
'   End Sub

'   Sub OnSMTPData(oClient, oMessage)
'   End Sub

'   Sub OnAcceptMessage(oClient, oMessage)
'   End Sub

'   Sub OnDeliveryStart(oMessage)
'   End Sub

'   Sub OnDeliverMessage(oMessage)
'   End Sub

'   Sub OnBackupFailed(sReason)
'   End Sub

'   Sub OnBackupCompleted()
'   End Sub

'   Sub OnError(iSeverity, iCode, sSource, sDescription)
'   End Sub

'   Sub OnDeliveryFailed(oMessage, sRecipient, sErrorMessage)
'   End Sub

'   Sub OnExternalAccountDownload(oFetchAccount, oMessage, sRemoteUID)
'   End Sub


Sub OnDeliverMessage(oMessage)

   Const strRecipient1 = "contact@example.com"            ' <-- Change to reflect actual user!
   Const strRecipient2 = "nospam@example.com"
   Const strRegEx     = "(\?)(gb(k|2312|18030)|big5|euc-(cn|tw)|shift|iso-2022-(cn|jp))(\?)"  ' <-- Here you can add search params!

   Dim i, ECFlag : ECFlag = oMessage.EncodeFields
   For i = 0 To oMessage.Recipients.Count-1
      If oMessage.Recipients(i).Address = strRecipient1 or oMessage.Recipients(i).Address = strRecipient2 Then
         oMessage.EncodeFields = False
         With CreateObject("VBScript.RegExp")
            .Pattern = strRegEx
            .Global = True
            .MultiLine = True
            .IgnoreCase = True
            If .Test(oMessage.From) Then
               oMessage.HeaderValue("X-hMailServer-Mime-Ban") = "YES"
            End If
            If .Test(oMessage.Subject) Then
               oMessage.HeaderValue("X-hMailServer-Mime-Ban") = "YES"
            End If
         End With
         oMessage.Save
         oMessage.EncodeFields = ECFlag
      End If
   Next
	
	'Commence bad word filter

	Dim strWords
	'Dim i
	Dim strBadWord
	Dim blnReject
	Dim dicWordCount
	Dim dicWordScore
	Dim intBadWordCount : intBadWordCount = 0
	Dim intBadScore
	Dim strLine


	Const THRESHOLD = 50
	Dim Location : Location = "C:\Program Files (x86)\hMailServer\block-list.txt"
	 
	Dim strBody : strBody = LCase(oMessage.Body)
	Dim strHTMLBody : strHTMLBody = LCase(oMessage.HTMLBody)
	Dim strSubject : strSubject = LCase(oMessage.Subject)
	
'	If strHTMLBody = "" Then
'	strHTMLBody = strBody
'	End If 
	
'	strHTMLBody = Base64Decode(strHTMLBody)
	


	Set dicWordCount = CreateObject("Scripting.Dictionary")
	Set dicWordScore = CreateObject("Scripting.Dictionary")


	Set objFSO = CreateObject("Scripting.FileSystemObject")
	Set objTextFile = objFSO.OpenTextFile(Location, 1)

	Do While objTextFile.AtEndOfStream <> True
	strLine = objTextFile.Readline

	If Len(strLine) >=2 And InStr(strLine,",") >=1 Then
	arrWords = Split(strLine, ",")
	strBadWord = Trim(arrWords(0))
	intBadScore =  Int(Trim(arrWords(1)))

	If InStr(strSubject,strBadWord) >=1 Then
	intBadWords = Int(UBound(Split(strSubject,strBadWord))) * intBadScore

	If dicWordCount.Exists(strBadWord) = False Then
	   dicWordCount.Add strBadWord,intBadWords
	End If
	End If


	If InStr(strBody,strBadWord) >=1 Then
	intBadWords = Int(UBound(Split(strBody,strBadWord))) * intBadScore

	If dicWordCount.Exists(strBadWord) = False Then
	   dicWordCount.Add strBadWord,intBadWords
	Else
	   dicWordCount.Item(strBadWord) = Int(dicWordCount.Item(strBadWord)) + intBadWords
	End If
	End If


	If InStr(strHTMLBody,strBadWord) >=1 Then
	intBadWords = Int(UBound(Split(strHTMLBody,strBadWord))) * intBadScore

	If dicWordCount.Exists(strBadWord) = False Then
	   dicWordCount.Add strBadWord,intBadWords
	Else
	   dicWordCount.Item(strBadWord) = Int(dicWordCount.Item(strBadWord)) + intBadWords
	End If
	End If

	End If
	Loop

	objTextFile.Close()


	arrBadWordCount = dicWordCount.Items
	arrBadWords = dicWordCount.Keys
		   

	For i = 0 To UBound(arrBadWordCount)
	intBadWordCount = Int(arrBadWordCount(i)) + intBadWordCount
	Next

	If intBadWordCount >= THRESHOLD Then
	oMessage.HeaderValue("X-hMailServer-Mime-Ban") = "YES"
	Result.Value = 1
	For i = 0 To UBound(arrBadWords)
	strLogs = arrBadWords(i)& " " & arrBadWordCount(i)
	Next
	
	EventLog.Write( "Not delivered  " & oMessage.From & " " & strLogs & " Total: " & intBadWordCount)
	
	Else
	Result.Value = 0
	'EventLog.Write( "delivered" )
	If dicWordCount.count >=1  Then
	For i = 0 To UBound(arrBadWords)
	strLogs = arrBadWords(i)& " " & arrBadWordCount(i)
	Next
	End If 
	
	'EventLog.Write( "Delivered  " & oMessage.From & " " & strLogs & " Total: " & intBadWordCount)
	
	
	End If
	  
End Sub

Function Base64Encode(sText)
    Dim oXML, oNode
    Set oXML = CreateObject("Msxml2.DOMDocument.3.0")
    Set oNode = oXML.CreateElement("base64")
    oNode.dataType = "bin.base64"
    oNode.nodeTypedValue = Stream_StringToBinary(sText)
    Base64Encode = oNode.text
    Set oNode = Nothing
    Set oXML = Nothing
End Function
 
Function Base64Decode(ByVal vCode)
    Dim oXML, oNode
    Set oXML = CreateObject("Msxml2.DOMDocument.3.0")
    Set oNode = oXML.CreateElement("base64")
    oNode.dataType = "bin.base64"
    oNode.text = vCode
    Base64Decode = Stream_BinaryToString(oNode.nodeTypedValue)
    Set oNode = Nothing
    Set oXML = Nothing
End Function
 
Private Function Stream_StringToBinary(Text)
  Const adTypeText = 2
  Const adTypeBinary = 1
  Dim BinaryStream 'As New Stream
  Set BinaryStream = CreateObject("ADODB.Stream")
  BinaryStream.Type = adTypeText
  BinaryStream.CharSet = "us-ascii"
  BinaryStream.Open
  BinaryStream.WriteText Text
  BinaryStream.Position = 0
  BinaryStream.Type = adTypeBinary
  BinaryStream.Position = 0
  Stream_StringToBinary = BinaryStream.Read
  Set BinaryStream = Nothing
End Function
 
Private Function Stream_BinaryToString(Binary)
  Const adTypeText = 2
  Const adTypeBinary = 1
  Dim BinaryStream 'As New Stream
  Set BinaryStream = CreateObject("ADODB.Stream")
  BinaryStream.Type = adTypeBinary
  BinaryStream.Open
  BinaryStream.Write Binary
  BinaryStream.Position = 0
  BinaryStream.Type = adTypeText
  BinaryStream.CharSet = "us-ascii"
  Stream_BinaryToString = BinaryStream.ReadText
  Set BinaryStream = Nothing
End Function


1Icarus2
New user
New user
Posts: 3
Joined: 2020-01-03 18:20

Re: How Do I Block All Mail Containing a Specific String

Post by 1Icarus2 » 2020-01-04 16:23

I see as part of your new code you did build in the decoding. What do you mean it is not working? :(

Kendo
Normal user
Normal user
Posts: 100
Joined: 2015-07-08 23:33
Location: Rural Australia

Re: How Do I Block All Mail Containing a Specific String

Post by Kendo » 2020-01-04 23:41

The functions are there. But if they are being used, then it doesn't work. It didn't work in our tests.

There is also a function for detecting asian spam, but that doesn't work either.

Any improvement on those will be greatly appreciated :-)

Kendo
Normal user
Normal user
Posts: 100
Joined: 2015-07-08 23:33
Location: Rural Australia

Re: How Do I Block All Mail Containing a Specific String

Post by Kendo » 2020-04-28 07:13

Has anyone been able to get the decoding to work so that the word filter can be applied to encoded mail messages?

Post Reply