mailcow / mailcow-dockerized

mailcow: dockerized - 🐮 + 🐋 = 💕
https://mailcow.email
GNU General Public License v3.0
8.5k stars 1.14k forks source link

Block attachments based on file extension #5076

Open KiwiActinidia opened 1 year ago

KiwiActinidia commented 1 year ago

Summary

I'm requesting to add to "Global filter maps" a new map to block some file extension. Actually I added do rspamd multimap.conf file this rule:

BAD_FILE_EXT { type = "filename"; filter = "extension"; map = "${LOCAL_CONFDIR}/custom/bad_file_ext.map"; symbol = "FILENAME BLACKLISTED" action = "reject"; }

Motivation

Sometimes, phishing attack it's based on opening the attached file to email. The file extension is .ISO, .IMG, .ARJ, .LZH, .R01, .R02, .001 but also .REG, .EXE, .JS and many others. If an email have a file with these extension, I want do reject it. No virus check but simply reject it. Now for updating this file I must login to my server console. The rule can also be used to block some file for policy reason.

Many thanks Alessandro

Additional context

No response

master2die commented 1 year ago

I think the right approach would be a filter in Sieve. This filter could also be adjusted more precisely. Rspamd seems to me to be a possible approach here, which however strongly generalizes, so that I recommend you to have a closer look at the filters in Sieve.

edit: try this. I added some kind of reject message, so "honest" senders will know precisely why it was rejected.

require ["fileinto", "reject"];

if anyof (header :contains "Content-Type" "application/octet-stream",
          header :contains "Content-Type" "application/x-rar-compressed",
          header :contains "Content-Type" "application/x-zip-compressed",
          header :contains "Content-Type" "multipart/x-zip") {
  if anyof (header :contains "Content-Disposition" "attachment; filename=*.iso",
            header :contains "Content-Disposition" "attachment; filename=*.img",
            header :contains "Content-Disposition" "attachment; filename=*.arj",
            header :contains "Content-Disposition" "attachment; filename=*.lzh",
            header :contains "Content-Disposition" "attachment; filename=*.r01",
            header :contains "Content-Disposition" "attachment; filename=*.r02",
            header :contains "Content-Disposition" "attachment; filename=*.001",
            header :contains "Content-Disposition" "attachment; filename=*.reg",
            header :contains "Content-Disposition" "attachment; filename=*.exe",
            header :contains "Content-Disposition" "attachment; filename=*.js") {
    reject "bad file extension CUSTOMIZE THIS REJECTION MESSAGE";
  }
}

Let me know if this worked for you :)

KiwiActinidia commented 1 year ago

I have about 200 hundreds email used only for working contacts. I found more simple to use rspamd. Rspamd search also into zip. If we receive .EXE no question "deny it". Also .ISO, .IMG and many other not frequent extension is used for malware. I scan only common extensions like xls, doc and pdf. Actually first problem is document with macro. My suggested filter it's another choice: if empty do nothing. It's like ASN or bad words filter. My list actually contains about 200 denied extensions.

Thanks Alessandro

philipp-s06 commented 1 year ago

I used the template prefilter for the list of blocked attatchments and customized it.

if anyof (body :raw :regex ["filename=.*\.doc","filename=.*\.docx","filename=.*\.docm","filename=.*\.xls","filename=.*\.xlsx","filename=.*\.xlsm","filename=.*\.mp3","filename=.*\.avi","filename=.*\.mov","filename=.*\.wav","filename=.*\.iso","filename=.*\.img","filename=.*\.gif","filename=.*\.png","filename=.*\.jpg","filename=.*\.jpeg","filename=.*\.scr","filename=.*\.vbs","filename=.*\.bat","filename=.*\.sh","filename=.*\.bash","filename=.*\.cmd","filename=.*\.apk","filename=.*\.com","filename=.*\.msi","filename=.*\.vbr","filename=.*\.ws","filename=.*\.wsf","filename=.*\.scf","filename=.*\.exe"]) {
  reject text:
my reject text :)
.
;
}

But with this filter it blocks EVERY mail with EVERY file extensions. What is wrong with this filter? Please help :(

philipp-s06 commented 1 year ago

I think the right approach would be a filter in Sieve. This filter could also be adjusted more precisely. Rspamd seems to me to be a possible approach here, which however strongly generalizes, so that I recommend you to have a closer look at the filters in Sieve.

edit: try this. I added some kind of reject message, so "honest" senders will know precisely why it was rejected.

require ["fileinto", "reject"];

if anyof (header :contains "Content-Type" "application/octet-stream",
          header :contains "Content-Type" "application/x-rar-compressed",
          header :contains "Content-Type" "application/x-zip-compressed",
          header :contains "Content-Type" "multipart/x-zip") {
  if anyof (header :contains "Content-Disposition" "attachment; filename=*.iso",
            header :contains "Content-Disposition" "attachment; filename=*.img",
            header :contains "Content-Disposition" "attachment; filename=*.arj",
            header :contains "Content-Disposition" "attachment; filename=*.lzh",
            header :contains "Content-Disposition" "attachment; filename=*.r01",
            header :contains "Content-Disposition" "attachment; filename=*.r02",
            header :contains "Content-Disposition" "attachment; filename=*.001",
            header :contains "Content-Disposition" "attachment; filename=*.reg",
            header :contains "Content-Disposition" "attachment; filename=*.exe",
            header :contains "Content-Disposition" "attachment; filename=*.js") {
    reject "bad file extension CUSTOMIZE THIS REJECTION MESSAGE";
  }
}

Let me know if this worked for you :)

This filter doesn't work for me.

81packet commented 1 year ago

I used the template prefilter for the list of blocked attatchments and customized it.

if anyof (body :raw :regex ["filename=.*\.doc","filename=.*\.docx","filename=.*\.docm","filename=.*\.xls","filename=.*\.xlsx","filename=.*\.xlsm","filename=.*\.mp3","filename=.*\.avi","filename=.*\.mov","filename=.*\.wav","filename=.*\.iso","filename=.*\.img","filename=.*\.gif","filename=.*\.png","filename=.*\.jpg","filename=.*\.jpeg","filename=.*\.scr","filename=.*\.vbs","filename=.*\.bat","filename=.*\.sh","filename=.*\.bash","filename=.*\.cmd","filename=.*\.apk","filename=.*\.com","filename=.*\.msi","filename=.*\.vbr","filename=.*\.ws","filename=.*\.wsf","filename=.*\.scf","filename=.*\.exe"]) {
  reject text:
my reject text :)
.
;
}

But with this filter it blocks EVERY mail with EVERY file extensions. What is wrong with this filter? Please help :(

Did you manage to solve the problem of blocking all attachments? Full reinstall didn't help. (I thought the problem was that I broke the configuration file somewhere)

philipp-s06 commented 1 year ago

Did you manage to solve the problem of blocking all attachments?

Unfortunly not. I don't have more ideas. I Hope someone can help with that problem.

81packet commented 1 year ago

Did you manage to solve the problem of blocking all attachments?

Unfortunly not. I don't have more ideas. I Hope someone can help with that problem.

As an option:

require ["reject","body","regex","notify"];
if anyof (body :raw :regex ["filename=.*\.pdf","filename=.*\.doc","filename=.*\.xls","filename=.*\.gif","filename=.*\.docx","filename=.*\.xlsx"]) {
keep;  # The filter skips the necessary extensions
if anyof (body :raw :regex ["filename=.*\.gz","filename=.*\.exe","filename=.*\.js","filename=.*\.zip","filename=.*\.rar","filename=.*\.7z"]) {
 redirect "blocked@domain.com";  # The filter sends to the desired mail

You just need to write it down correctly or bring it to mind. Split into two filters. So that one skips the necessary attachments, the second blocks

81packet commented 1 year ago

Did you manage to solve the problem of blocking all attachments?

Unfortunly not. I don't have more ideas. I Hope someone can help with that problem.

Friends! After long and exhausting attempts, I found a solution to the problem:

require ["fileinto","reject","body","regex","notify"];
if anyof (body :raw :regex "filename=.*\.rar",
          body :raw :regex "filename=.*\.zip",
      body :raw :regex "filename=.*\.7z",
      body :raw :regex "filename=.*\.exe",
          body :raw :regex "filename=.*\.moo")
{
 if not anyof (body :raw :regex "filename=.*\.(jpg|jpeg|pdf|doc)")
    {
 redirect "blocked@domain.com";  
philipp-s06 commented 1 year ago

solution to the problem

It might work but the sender won't be notified about the blocked mail with a bad file extension.

81packet commented 1 year ago

solution to the problem

It might work but the sender won't be notified about the blocked mail with a bad file extension.

require ["fileinto","reject","body","regex","notify"];
if anyof (body :raw :regex "filename=.*\.rar",
          body :raw :regex "filename=.*\.zip",
      body :raw :regex "filename=.*\.7z",
      body :raw :regex "filename=.*\.exe",
          body :raw :regex "filename=.*\.moo")
{
 if not anyof (body :raw :regex "filename=.*\.(jpg|jpeg|pdf|doc)")
    {
 redirect "blocked@domain.com"; 
notify :low :message " Warning notify bla bla bla" :method "mailto" :options ["user@domain.com"];
philipp-s06 commented 1 year ago

options ["user@domain.com"];

But what if the sender is not from our mailcow?

81packet commented 1 year ago

options ["user@domain.com"];

But what if the sender is not from our mailcow?

This is a general rule for every user. Change only the mailto address

philipp-s06 commented 1 year ago

Mailcow says "Unexpected tag :options".

philipp-s06 commented 1 year ago

I also tried that filter: if anyof (body :raw :regex "filename=.*\.rar", body :raw :regex "filename=.*\.zip", body :raw :regex "filename=.*\.7z", body :raw :regex "filename=.*\.exe", body :raw :regex "filename=.*\.msi") { if not anyof (body :raw :regex "filename=.*\.(jpg|jpeg|pdf|docx|xlsx|pptx|gif|png|html|htm|txt|)") { reject text: bla text . ; } }

and it doesn't work... whats wrong with that hell.....

81packet commented 1 year ago

Mailcow says "Unexpected tag :options".

https://github.com/mailcow/mailcow-dockerized/issues/5246 fix it

philipp-s06 commented 1 year ago

Ok now Mailcow accepts the syntax but the filter doens't work. Mails with a .zip file are normally delivered without any notification to the sender. I want that the Mail with a bad extension should be rejected and the sender gets a mail with a notification.

81packet commented 1 year ago

I raised another mail server with sieve support for the test, and the rule we needed normally worked there, but with mime and enotify. Example:

require ["enotify","fileinto","mime"];
if header :contains "from" "@domain.com"
{
    fileinto "INBOX";
    stop;
}

if header :mime :anychild :param "filename" :matches "Content-Disposition" ["*.pdf","*.doc"]
{
    fileinto "INBOX";
    stop;
}

if header :mime :anychild :param "filename" :matches "content-disposition" ["*.rar","*.zip"]
{
    redirect "blocked@domain.com";
    notify :importance "3" :message "New message in blablabla..." "mailto:name@domain.com";
    stop;
}

We need to fix the problem with "mime" and "enotify" and everyone will be happy.